改寫了這個問題。如何使cMake只爲項目中的子目錄使用調試編譯模式?
我有以下問題:
我的項目有幾個二進制文件和庫駐留在主項目文件夾下不同的子目錄。 只需調試其中的一個子集就可以了,而無需在Debug模式下重新編譯整個項目。
我想只能以半自動方式更改此子集的編譯模式。
我該如何使用CMake來完成這項工作?
改寫了這個問題。如何使cMake只爲項目中的子目錄使用調試編譯模式?
我有以下問題:
我的項目有幾個二進制文件和庫駐留在主項目文件夾下不同的子目錄。 只需調試其中的一個子集就可以了,而無需在Debug模式下重新編譯整個項目。
我想只能以半自動方式更改此子集的編譯模式。
我該如何使用CMake來完成這項工作?
如果更改構建類型,整個項目將從頭開始重新編譯。通常你保持2個獨立的構建樹,一個配置的調試和一個配置的版本。
請注意,CMAKE_BUILD_TYPE
可以通過命令行或cmake-gui進行設置,不應將其設置在CMakeLists.txt文件中。
macro (CHECK_IF_DEBUG)
if (NOT (CMAKE_BUILD_TYPE MATCHES Debug))
get_filename_component(THIS_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME)
STRING(REGEX REPLACE " " "_" THIS_DIR ${THIS_DIR}) #Replace spaces with underscores
if (DEFINED DEBUG_${THIS_DIR})
message(STATUS "Note: Targets in directory ${THIS_DIR} will be built Debug") #A reminder
set (CMAKE_BUILD_TYPE Debug)
endif()
endif()
endmacro()
然後,在每個子目錄添加(在的CMakeLists.txt的開頭)宏調用
CHECK_IF_DEBUG()
當你需要臨時調試項目的一個部分(子目錄)時,用cmake-gui打開你的項目,並定義一個名爲DEBUG_<DirectoryName>
的變量(「Add Entry」)。你可以定義多個。 如果您的目錄名稱中包含空格,請在變量名稱中替換爲下劃線。不要忘記點擊cmake-gui中的Configure
和Generate
以使更改生效。分配給變量的值不重要,可以留空。
當你完成調試時,回到cmake-gui並刪除相應的條目。 別忘了Configure
和Generate
。
我已經在一個小項目中測試過它,它似乎正常工作。
注:如果您在同一的CMakeLists.txt創建多個目標(add_library
或add_executable
)(=在同一個子目錄),我還沒有找到一個辦法讓一個目標建立在一種方式,一個目標在另一種情況下:似乎要計數的唯一東西是CMake完成解析文件時CMAKE_BUILD_TYPE
目錄的值。
在回答您的意見,您可以通過塊加入如下一行在生成時打印的提示:
add_custom_target(info_${THIS_DIR} ALL COMMAND echo Targets in directory ${THIS_DIR} are built Debug)
如果你閱讀我的問題,你會看到我想在調試模式下編譯它的一部分。有時候這是必要的,否則我可能會有太多與手頭問題無關的調試消息。 –
@MarcoCosta正如你從2個反應中看到的那樣,問題根本不明確。它可能會變成一個有趣的,所以它是值得重新修飾它。 – Antonio
我編輯了問題和標題。感謝您對如何更好地提出問題的意見。 –
我想出瞭解決辦法如下:
我創建了一個宏,將讀取的二進制目錄中的配置文件,並設置基於其內容的編輯類型。
當此文件發生更改時,cMake將僅重新運行該目錄,並且還會重新編譯它,因爲它的依賴關係已更改。這正是我需要的。
宏如下:
macro(set_buildmode _local_app_name)
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/BUILDMODE)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/BUILDMODE ${CMAKE_BUILD_TYPE})
message(" *** Creating file 'BUILDMODE' with type '${CMAKE_BUILD_TYPE}' for '${_local_app_name}'")
endif()
configure_file(${CMAKE_CURRENT_BINARY_DIR}/BUILDMODE
${CMAKE_CURRENT_BINARY_DIR}/BUILDMODE.junk)
file(READ ${CMAKE_CURRENT_BINARY_DIR}/BUILDMODE CMAKE_BUILD_TYPE)
string(STRIP ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
endmacro()
爲了確保我總是知道我比發行以外的任何其他模式已編制,我也有這個宏:
macro(add_buildmode_message _local_app_name_full)
get_filename_component(_local_app_name ${_local_app_name_full} NAME)
add_custom_target(Checking_BUILDMODE_for_${_local_app_name} ALL
COMMAND bash -c "if [ \"${CMAKE_BUILD_TYPE}\" != \"Release\" ] ; then echo -e \" ${BoldRed}${_local_app_name} was built with type '${CMAKE_BUILD_TYPE}'${ColourReset}\" ; fi"
VERBATIM)
endmacro()
下面是一個例子它的用法:
set(appname example)
###### Call set_buildmode here
set_buildmode(${appname})
set(${appname}_SRCS
example.cpp
main.cpp)
set(${appname}_HDRS
example.h)
set(${appname}_LIBS)
set(BUILD_SHARED_LIBS ON)
execute_process(COMMAND ln -frs ${${appname}_HDRS} ${CMAKE_BINARY_DIR}/include/
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(MYLIB_VERSION_MAJOR 2)
set(MYLIB_VERSION_MINOR 1)
set(MYLIB_VERSION_PATCH 0)
set(MYLIB_VERSION_STRING
${MYLIB_VERSION_MAJOR}.${MYLIB_VERSION_MINOR}.${MYLIB_VERSION_PATCH})
add_library(${appname} ${${appname}_SRCS})
target_link_libraries (${appname} ${${appname}_LIBS} ${CMAKE_THREAD_LIBS_INIT})
##### Add the fake target for checking the build mode
add_buildmode_message(${appname})
set_target_properties(${appname} PROPERTIES VERSION ${MYLIB_VERSION_STRING}
SOVERSION ${MYLIB_VERSION_MAJOR})
install(TARGETS ${appname} DESTINATION lib)
在CMake invokation期間傳遞構建類型如何?像'cmake .. -DCMAKE_BUILD_TYPE = Debug'。 – Kamiccolo
僅當我想在調試模式下編譯整個項目。 –