C++ C为多个项目创建一个构建目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34438357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CMake one build directory for multiple projects
提问by Mendes
I′m a beginner user of CMake. My environment has several projects like:
我是 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
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.
我想为每个项目使用一个构建目录,如上所示。最好是它可以分成多个子项目,比如build/projectA
,build/ProjectB
这样如果我需要重建一个项目,我可以删除整个build/Project
文件,一切都消失了,一个新的Cmake
将再次构建它。
I′m having difficulties configuring CMAKE.
我在配置 CMAKE 时遇到了困难。
My original CMakeList.txt on the project folder:
我在项目文件夹中的原始 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)
My questions are:
我的问题是:
A) What will happen if I run cmake on a single build directory - is that possible and what would be the correct CMAKE configuration ?
A)如果我在单个构建目录上运行 cmake 会发生什么 - 这可能吗?正确的 CMAKE 配置是什么?
B) My compilation for ProjectA
needs to include files from ProjectB
- how can I set that in the CMakeLists.txt
for each individual project ?
B)我的编译ProjectA
需要包含来自的文件ProjectB
- 我如何在CMakeLists.txt
每个单独的项目中设置它?
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 ?
C) 最后,我需要一个单独的 makefile 来构建所有项目,以及单独构建每个项目的选项。使用单个构建目录可以实现吗?
Thanks for helping.
谢谢你的帮助。
回答by SirDarius
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 代码不属于顶级 CMakeList.txt 文件,因为它直接引用了 .cpp 文件和“projectA”。还有一些不习惯的事情:
cmake_minimum_required(VERSION 3.2.2.)
why the trailing dot here ? Not sure whether cmake will complain, but it is useless either way.
为什么这里的尾随点?不确定 cmake 是否会抱怨,但无论哪种方式都没用。
set(CMAKE_BUILD_TYPE Debug)
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.
不要那样做。而是使用-DCMAKE_BUILD_TYPE=Debug
命令行标志调用 cmake ,或使用 ccmake 或 GUI,或编辑 CMakeCache.txt 文件。
file(GLOB SOURCES "*.cpp")
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.
也不要那样做。在 CMake 中明确列出源文件是一种很好的做法,因为 globbing 不会使 cmake 自动检测新添加或删除的文件。不过,有些人可能不同意。
Now for the heart of the topic, here is how things are usually done:
现在对于主题的核心,以下是通常的做法:
Top CMakeLists.txt file:
顶部 CMakeLists.txt 文件:
cmake_minimum_required(VERSION 3.2.2)
project(globalProject)
add_subdirectory(projectA)
add_subdirectory(projectB)
ProjectA CMakeLists.txt file (assuming projectA is an executable):
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 file (assuming projectB is a library):
ProjectB CMakeLists.txt 文件(假设 projectB 是一个库):
add_library(projectB file1.cpp file2.cpp ... )
install(TARGETS projectB
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
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).
请注意,此设置需要在make install
您选择的位置创建 bin 和 lib的步骤,如 cmake 的命令行调用中给出的-DCMAKE_INSTALL_PREFIX=..
(假设 make 从构建目录运行)。
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.
此外,此设置可让您选择是要构建静态库还是共享库,方法是使用:-DBUILD_SHARED_LIBS=ON
. 要构建两者,您需要有两个add_library
具有两个不同名称的调用,一个是 STATIC,另一个是 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) it is possible and recommended, see the code above, only one build directory is necessary.
A) 有可能且推荐,见上面的代码,只需要一个构建目录。
B) See the code for the projectA/CMakeLists.txt, you have to call include_directories()
B)查看projectA/CMakeLists.txt的代码,你要调用 include_directories()
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
C) 是的,这是可能的。项目中的每个目标都可以通过使用 make 和目标名称从构建目录单独构建:make projectB
和make projectA
回答by Pierre Emmanuel Lallemant
A) You can do 1 CMakeLists.txt for N projects. When you define a library, you can use it in an executable defined in the cmake (add_executable and target_link_libraries to see).
A) 您可以为 N 个项目执行 1 个 CMakeLists.txt。定义库时,可以在cmake中定义的可执行文件中使用(add_executable和target_link_libraries查看)。
B) see target_include_directories
B) 见 target_include_directories
C) it seems you can call cmake --target target
to generate the Makefile for only one of the target of your cmakelists.txt file.
C) 似乎您可以调用cmake --target target
仅为 cmakelists.txt 文件的目标之一生成 Makefile。