CMake一个用于多个项目的构建目录 [英] CMake one build directory for multiple projects

查看:146
本文介绍了CMake一个用于多个项目的构建目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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/projectAbuild/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文件,并且"projectA". 还有一些不习惯的东西:

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步骤,以在cmake -DCMAKE_INSTALL_PREFIX=..的命令行调用中给定的位置上创建bin和lib(假设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 projectBmake 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

这篇关于CMake一个用于多个项目的构建目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆