C为多个项目创建一个构建目录
我是 CMake 的初学者.我的环境有几个项目,例如:
I′m a beginner user of CMake. My environment has several projects like:
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
将再次构建它.
I would like to use a single build directory for every project, as showed above. Preferrably that It can be divided into multiple subprojects, like build/projectA
, build/ProjectB
so that if I need to rebuild a single project I can delete the whole build/Project
file and all is gone and a new Cmake
will build it again.
我在配置 CMAKE 时遇到了困难.
I′m having difficulties configuring CMAKE.
我在项目文件夹中的原始 CMakeList.txt:
My original CMakeList.txt on the project folder:
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 配置是什么?
A) What will happen if I run cmake on a single build directory - is that possible and what would be the correct CMAKE configuration ?
B) 我对 ProjectA
的编译需要包含来自 ProjectB
的文件 - 我如何在 CMakeLists.txt
中为每个人设置它项目?
B) My compilation for ProjectA
needs to include files from ProjectB
- how can I set that in the CMakeLists.txt
for each individual project ?
C) 最后,我需要一个单独的 makefile 来构建所有项目,以及单独构建每个项目的选项.使用单个构建目录可以实现吗?
C) At the end I need a single makefile to build all, as well as the option to build each project individually. Will that be possible with a single build directory ?
感谢您的帮助.
推荐答案
首先,你贴出来的 CMake 代码看起来不像是顶层的 CMakeList.txt 文件,因为它直接引用了 .cpp 文件,并且项目A".还有一些不太习惯的东西:
First of all, it doesn't look like the CMake code you posted belongs to the top CMakeList.txt file, since it directly references .cpp files, and "projectA". There are also a few things that are not idiomatic:
cmake_minimum_required(VERSION 3.2.2.)
为什么这里有尾随点?不确定 cmake 是否会抱怨,但无论如何都没用.
why the trailing dot here ? Not sure whether cmake will complain, but it is useless either way.
set(CMAKE_BUILD_TYPE Debug)
不要那样做.而是使用 -DCMAKE_BUILD_TYPE=Debug
命令行标志调用 cmake,或者使用 ccmake 或 GUI,或者编辑 CMakeCache.txt 文件.
Don't do that. Instead invoke cmake using the -DCMAKE_BUILD_TYPE=Debug
command line flag, or use ccmake, or a GUI, or edit the CMakeCache.txt file.
file(GLOB SOURCES "*.cpp")
也不要那样做.在 CMake 中明确列出源文件是一种很好的做法,因为 globbing 不会使 cmake 自动检测新添加或删除的文件.不过,有些人可能不同意.
Don't do that either. It is good practice to explicitely list source files in CMake, because globbing will not make cmake detect newly added or deleted files automatically. Some people might disagree though.
现在是主题的核心,以下是通常的处理方式:
Now for the heart of the topic, here is how things are usually done:
顶级 CMakeLists.txt 文件:
Top CMakeLists.txt file:
cmake_minimum_required(VERSION 3.2.2)
project(globalProject)
add_subdirectory(projectA)
add_subdirectory(projectB)
ProjectA CMakeLists.txt 文件(假设 projectA 是一个可执行文件):
ProjectA CMakeLists.txt file (assuming projectA is an executable):
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 是一个库):
ProjectB CMakeLists.txt file (assuming projectB is a library):
add_library(projectB file1.cpp file2.cpp ... )
install(TARGETS projectB
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
请注意,此设置需要 make install
步骤以在您选择的位置创建 bin 和 lib,如 cmake -DCMAKE_INSTALL_PREFIX=.. 的命令行调用中给出的.代码>(假设从构建目录运行 make).
Please note that this setup needs the make install
step to create bin and lib at the location of your choice as given in the command line invocation of cmake -DCMAKE_INSTALL_PREFIX=..
(assuming make is run from the build dir).
此外,此设置可让您通过使用:-DBUILD_SHARED_LIBS=ON
来选择是要构建静态库还是共享库.要同时构建两者,您需要使用两个不同名称的两个 add_library
调用,一个是 STATIC,另一个是 SHARED.
Also, this setup lets you choose if you want to build static or shared libraries, by using: -DBUILD_SHARED_LIBS=ON
. To build both, you need to have two add_library
calls with two different names, one STATIC, the other SHARED.
总结完成这项工作所需的步骤:
To sum up the steps required to make this work:
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON
$ make
$ make install
您可以将这些命令放在脚本中以实现可重用性.
You could put these commands in a script for reusability.
现在,您的问题可以得到解答:
Now, your questions can be answered:
A) 有可能且推荐,见上面的代码,只需要一个构建目录.
A) it is possible and recommended, see the code above, only one build directory is necessary.
B) 看projectA/CMakeLists.txt的代码,必须调用include_directories()
B) See the code for the projectA/CMakeLists.txt, you have to call include_directories()
C) 是的,这是可能的.可以使用 make 和目标名称从构建目录中单独构建项目中的每个目标:make projectB
和 make projectA
C) Yes it is possible. Each target in your project can be built individually from the build directory by using make and the target name: make projectB
and make projectA
相关文章