我是CMake的初学者用户。我的环境有几个项目,如:
project
|------ CMakeLists.txt (The main Cmake)
|------ ProjectA
| |----- .cpp files
| |----- .hpp files
| |----- CMakeList.txt
|------ ProjectB
| |----- .cpp files
| |----- .hpp files
| |----- CMakeList.txt
|
|------ build
| |----- CMakeStuff
|------ bin
| |---- executables
|------ lib
| |---- libwhatever.a
|------ db
|---- Database stuff
我想为每个项目使用一个构建目录,如上所示。优选地,它可以分为多个子项目,例如build/projectA
,build/ProjectB
,这样如果我需要重建单个项目,我可以删除整个build/Project
文件,所有文件都消失了Cmake
将再次构建它。
我在配置CMAKE时遇到了困难。
我在项目文件夹中的原始CMakeList.txt:
cmake_minimum_required(VERSION 3.2.2.)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin)
project(projectA)
set(CMAKE_BUILD_TYPE Debug)
file(GLOB SOURCES "*.cpp")
add_library(commonmessage SHARED ${SOURCES})
install(TARGETS commonmessage DESTINATION ../lib)
我的问题是:
A)如果我在单个构建目录上运行cmake会发生什么 - 这是可能的以及正确的CMAKE配置是什么?
B)我对ProjectA
的汇编需要包含来自ProjectB
的文件 - 如何在每个项目的CMakeLists.txt
中设置该文件?
C)最后,我需要一个makefile来构建所有,以及单独构建每个项目的选项。单个构建目录是否可以实现?
感谢您的帮助。
答案 0 :(得分:34)
首先,它看起来不像您发布的CMake代码属于顶级CMakeList.txt文件,因为它直接引用.cpp文件," projectA"。 还有一些不是惯用的东西:
cmake_minimum_required(VERSION 3.2.2.)
为什么这里的尾随点?不确定cmake是否会抱怨,但无论如何都没用。
set(CMAKE_BUILD_TYPE Debug)
不要这样做。而是使用-DCMAKE_BUILD_TYPE=Debug
命令行标志调用cmake,或使用ccmake或GUI,或编辑CMakeCache.txt文件。
file(GLOB SOURCES "*.cpp")
也不要这样做。在CMake中明确列出源文件是一种好习惯,因为globbing不会使cmake自动检测新添加或删除的文件。有些人可能不同意。
现在,关于这个主题的核心,以下是通常的工作方式:
热门CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.2.2)
project(globalProject)
add_subdirectory(projectA)
add_subdirectory(projectB)
ProjectA CMakeLists.txt文件(假设projectA是可执行文件):
add_executable(projectA file1.cpp file2.cpp ... )
include_directories(${CMAKE_SOURCE_DIR}/projectB) # include files from ProjectB
target_link_libraries(projectA projectB)
install(TARGETS projectA RUNTIME DESTINATION bin)
ProjectB CMakeLists.txt文件(假设projectB是一个库):
add_library(projectB file1.cpp file2.cpp ... )
install(TARGETS projectB
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
请注意,此设置需要make install
步骤在cmake -DCMAKE_INSTALL_PREFIX=..
的命令行调用中给出的所选位置创建bin和lib(假设make是从build dir运行的)。
此外,此设置允许您使用:-DBUILD_SHARED_LIBS=ON
选择是否要构建静态库或共享库。要构建两者,您需要进行两次add_library
次调用,其中一个是STATIC,另一个是SHARED。
总结完成这项工作所需的步骤:
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON
$ make
$ make install
您可以将这些命令放在脚本中以便重用。
现在,您的问题可以回答:
A)可以并且建议,参见上面的代码,只需要一个构建目录。
B)查看projectA / CMakeLists.txt的代码,你必须致电include_directories()
C)是的,这是可能的。您可以使用make和目标名称从构建目录中单独构建项目中的每个目标:make projectB
和make projectA
答案 1 :(得分:1)
A)您可以为N个项目执行1个CMakeLists.txt。定义库时,可以在cmake中定义的可执行文件中使用它(add_executable和target_link_libraries来查看)。
B)见target_include_directories
C)似乎你可以调用cmake --target target
为cmakelists.txt文件中的一个目标生成Makefile。