كيف أقوم بتكوين بنيات متوازية محمولة في CMake؟

StackOverflow https://stackoverflow.com//questions/10688549

  •  12-12-2019
  •  | 
  •  

سؤال

هل من الممكن بطريقة أو بأخرى أن تكون قادرًا على الحصول على بناء متوازي بغض النظر عن أداة البناء المستخدمة؟

تحت يونكس يمكننا أن نضيف make -jN حيث N هو عدد المواضيع، وتحت Windows قمت بإضافتها إلى CXX_FLAG "/MP" والذي يتم استخدامه بعد ذلك في Visual Studio للبناء المتوازي...(؟) كيف يمكنني جعل الإصدار الخاص بي بهذه الطريقة CMAKE_MAKE_PROGRAM لا يتم تمديده دائمًا عند تشغيل CMake؟

ما هو الحل العام؟

خطرت لي هذه:

# Add some multithreaded build support
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
set(MULTITHREADED_BUILD 12 CACHE STRING "How many threads are used to build the project")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            message(STATUS ${CMAKE_BUILD_TOOL})
            set(CMAKE_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM} -j${MULTITHREADED_BUILD}")
            message(STATUS "Added arguments to CMAKE_BUILD_TOOL: ${CMAKE_MAKE_PROGRAM}")
    elseif(MSVC)
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
      message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()
هل كانت مفيدة؟

المحلول

مع CMake 3.12 هذا ممكن.من ملاحظات الإصدار:

اكتسب وضع "Cmake (1)" وضع أداة البناء ("Cmake –Build") "-Parallel [] و "-j [] لتحديد مستوى البناء الموازي.إنهم يعينون الخيارات المقابلة لأداة البناء الأصلية.

كما ذكر dkg, ، يمكنك أيضًا تعيين متغير البيئة CMAKE_BUILD_PARALLEL_LEVEL.

روابط لوثائق CMake:

نصائح أخرى

إذا كان لديك CMake v2.8.8 أو أعلى، فيمكنك استخدام النينجا كبديل ل جنو make:

mkdir build
cd    build
cmake -G Ninja ..
ninja              # Parallel build (no need -j12)

أو

mkdir build
cd    build
cmake -G Ninja ..
cmake --build .    # Parallel build using Ninja

كما ترون، لا حاجة للاستخدام CMAKE_MAKE_PROGRAM, ، يتم تشغيل البناء بالتوازي بشكل افتراضي، مما يؤدي إلى تحسين عدد المهام اعتمادًا على مراكز وحدة المعالجة المركزية المتاحة.

يعتمد Ninja على تكوين JSON منخفض المستوى لتسريع مرحلة بدء التشغيل.لذلك ليس من السهل كتابة تكوين JSON يدويًا، وأنا دائمًا أقوم بإنشائه باستخدام أداة/IDE عالية المستوى:

نظرًا لأن إصدار C++ يتطلب غالبًا قدرًا كبيرًا من الذاكرة، فيجب أن يوفر جهاز الكمبيوتر الخاص بك قدرًا من الذاكرة يعادل عدد مراكز وحدة المعالجة المركزية (CPU).

كما أشار رسلان, ، كميك 3.12 (2018) لديه خيار جديد cmake --build -j <N> للحد من بناء ل <N> النوى (الوظائف) مما يحد من استهلاك الذاكرة (انظر أيضًا ملف توثيق).إذا كنت تستخدم إصدارًا أقدم من CMake، فلا يزال بإمكانك استخدامه cmake --build -- -j <N>.الخيار -- يخبر CMake بتمرير الباقي مباشرة إلى أداة الإنشاء الأساسية، وهنا Ninja.

لا يمكنك القيام بهذا عبر الأنظمة الأساسية.الخيار -jN هو معلمة يجب إنشاؤها، وليس جزءًا من ملف Makefile الذي تم إنشاؤه.ومع ذلك، يمكنك جعل CMake يقوم بإنشاء برنامج Bash النصي الذي يقوم بتشغيل make لمشروعك باستخدام -jN (حيث يبحث البرنامج النصي عن عدد النوى الموجودة لديك).

لقد استقرت على كتابة أ parallelmake.sh البرنامج النصي ل Unix Makefilesالمولدات القائمة.ويتم ذلك هنا: https://github.com/gabyx/ApproxMVBB

والأجزاء ذات الصلة في ملف CMake:

https://github.com/gabyx/ApproxMVBB/blob/master/CMakeLists.txt#L89

# Add some multithreaded build support =====================================================================================================
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
SET(MULTITHREADED_BUILD ON CACHE BOOL "Parallel build with as many threads as possible!")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            file(COPY ${ApproxMVBB_ROOT_DIR}/cmake/parallelmake.sh DESTINATION ${PROJECT_BINARY_DIR}
                FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
                NO_SOURCE_PERMISSIONS
            )
            SET(CMAKE_MAKE_PROGRAM "${PROJECT_BINARY_DIR}/parallelmake.sh")
            MESSAGE(STATUS "Set make program to ${PROJECT_BINARY_DIR}/parallelmake.sh")
    elseif(MSVC)
      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" "/MP")
      MESSAGE(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()
# ========================================================================================================================================
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top