首页 文章

为多个项目创建一个构建目录

提问于
浏览
17

我是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/projectAbuild/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来构建所有,以及单独构建每个项目的选项 . 单个构建目录是否可以实现?

谢谢你的帮助 .

2 回答

  • 1

    A)你可以为N个项目做1个CMakeLists.txt . 定义库时,可以在cmake中定义的可执行文件中使用它(add_executable和target_link_libraries来查看) .

    B)查看target_include_directories

    C)似乎你可以调用 cmake --target target 为你的cmakelists.txt文件的一个目标生成Makefile .

  • 28

    首先,它看起来不像您发布的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 步骤在您选择的位置创建bin和lib,如cmake -DCMAKE_INSTALL_PREFIX=.. 的命令行调用中所示(假设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 projectBmake projectA

相关问题