【问题标题】:CMake Multi-Project setup for Visual Studio 2017Visual Studio 2017 的 CMake 多项目设置
【发布时间】:2017-07-12 19:50:07
【问题描述】:

首先,我是 CMake 新手。

我想做的是从直接在 VS 2017 中编译我的解决方案切换到 CMake,以便在 Linux 等其他平台上轻松构建项目。

文件夹结构:

project
  |─── CMakeLists.txt
  |─── bin
  |     | ─── intermediates
  |     |       |─── Win32
  |     |       |      |─── Debug
  |     |       |      └─── Release
  |     |       └─── Linux
  |     |              |─── Debug
  |     |              └─── Release
  |     |─── Win32
  |     |      |─── Debug
  |     |      └─── Release
  |     └─── Linux
  |            |─── Debug
  |            └─── Release
  |─── include
  |─── Project 1
  |      |─── CMakeLists.txt
  |      |─── src
  |      |─── res
  |      └─── header
  └─── Project 2
         |─── CMakeLists.txt
         |─── src
         |─── res
         └─── header

CMake 文件

这是我的 CMakeLists,第一个用于根项目,第二个用于第一个项目和第二个项目:

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.8.2)

# Project's name
project(Project X)

# Set the C++ Version
message("!REQUIRED! -- Supported features = ${cxx_std_14}")
message("Supported features = ${cxx_std_17}")

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Set the output folder where the program will be created

set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})

# Add the modules
add_subdirectory(Project 1)
add_subdirectory(Project 2) # depends on Project 1

第一个和第二个项目的CMakeLists.txt,因为文件内容是一样的:

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.8.2)

project(Project 1)

# In order to find all cpp files automatically for compilation
file(GLOB CPP_FILES src/*.cpp)
file(GLOB CPP_FILES header/*.h)

# Set the version number of the project here
set(VERSION_MAJOR "0")
set(VERSION_MINOR "1")
set(VERSION_PATCH "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})

这是我的 VS 设置:

Output Directory:       $(SolutionDir)bin\$(Platform)\$(Configuration)\
Intermediate Directory: $(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\

在这种情况下,项目 B 是可执行文件,而项目 A 只是一个库,必须链接到项目 B 才能编译项目 B。

问题:

  • 如何将这些 Visual Studio 2017 设置应用到 CMake? (我该如何配置 CMAKE_BINARY_DIR 设置等)
  • 项目 2 取决于项目 1,CMake 会自动处理这个问题还是我必须在 CMakeLists.txt 中添加一些内容?

【问题讨论】:

    标签: c++ visual-studio compilation cmake visual-studio-2017


    【解决方案1】:

    有多个要解决的点:

    1. CMAKE_BINARY_DIR 就所有意图和目的而言,都是一个只读变量,绝对应该这样对待。指定二进制目录的方法是在该目录中运行 CMake(从命令行运行时),或将该目录设置为二进制/输出目录(使用 CMake GUI 时)。因此,在您的情况下,要实现您声称想要的设置,您可以这样做:

      > cd project/bin
      > cmake .. -G "Visual Studio whatever" ...
      

      (“whatever”当然是占位符)

      但是,我强烈建议您不要使用这样的布局。更好的布局将是纯粹的源外构建,如下所示:

      project
      project/source/CMakeLists.txt
      project/source/include
      project/source/...
      project/build/Win32
      project/build/Linux
      

      使用此设置,您将像这样运行:

      > cd project/build/Win32
      > cmake ../../source -G "Visual Studio whatever" ...
      
    2. 您在 CMake 中设置二进制输出路径的方式与您作为“VS 设置”呈现的内容之间存在冲突。我不知道你的 inteded 状态,但如果你想设置 CMake 以便你的二进制文件最终出现在你在 VS 设置中列出的输出目录中,你可以这样做:

      set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR})
      

      LIBRARY_OUTPUT_PATH 同上。

    3. 就设置中间目录而言,这是 CMake 自己管理的事情,您无法真正影响它。不过,问题是您为什么要这样做。

    4. 关于项目依赖关系:您没有显示实际创建二进制文件 (add_library()/add_executable()) 的 CMake 命令或设置其属性的命令。但是,如果您指定项目 2 创建的可执行文件链接到项目 1 创建的库,CMake 将正确跟踪依赖关系。你可以这样指定:

      target_link_libraries(targetNameOfProject2executable targetNameOfProject1library)
      
    5. 请注意,使用file(GLOB) 构造源文件列表是个坏主意,CMake 不鼓励这样做。原因很简单:添加源文件不会导致构建系统重新生成,这意味着源文件不会被拾取。如果您改为显式列出源文件,添加文件将意味着您必须将其添加到 CMakeList 中的列表(或包含在其中的文件中),这将触发构建系统的重新生成。

      李>
    6. Linux 的注意事项:与 Visual Studio 不同,Makefile 生成器(实际上是 CMake 的大多数生成器)是单一配置,这意味着您必须为每个配置生成一个构建系统。在 out-of-souce 设置中,您可以这样做:

      > cd project/build/Linux/Debug
      > cmake ../../../../source -DCMAKE_BUILD_TYPE=Debug ...
      > cd project/build/Linux/Release
      > cmake ../../../../source -DCMAKE_BUILD_TYPE=Release ...
      

    【讨论】:

    • 致 1: 您能否说明为什么“纯源外构建”会更好? 至 2: 我希望 CMake 设置与 VS 中的设置相同。 To 5:我怎样才能编译所有源文件,因为我不想手动编写数百个文件。
    • @ShadowDragon 1 这不是绝对必要的,但它是首选的 CMake 操作模式。 “CMake out-of-source”应该是可谷歌搜索的。但是您最初的想法(目录至少是不同的)也相当不错。 2 答案表明。它实际上也适用于您的“源代码不足”设置。 5 您可以将列表(set() 调用)移动到一个单独的文件中,您将使用include(),并使用脚本或其他东西第一次生成它。然后继续手动更新。
    猜你喜欢
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多