首先,我是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
这是我的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进行编译。
答案 0 :(得分:2)
有几点需要解决:
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" ...
您在CMake中设置二进制输出路径的方式与您提供的" VS设置之间存在冲突。"我不知道你的状态是哪个,但是如果你想设置CMake以便你的二进制文件最终出现在VS设置中列出的输出目录中,你可以这样做:
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR})
同上LIBRARY_OUTPUT_PATH
。
就设置中间目录而言,这是CMake管理自己的东西,你不能真正影响它。问题是你为什么要这样做。
关于项目依赖性:您还没有显示实际创建二进制文件(add_library()
/ add_executable()
)的CMake命令或设置其属性的命令。但是,如果指定Project 2创建的可执行文件链接到Project 1创建的库,则CMake将正确跟踪依赖项。您可以这样指定:
target_link_libraries(targetNameOfProject2executable targetNameOfProject1library)
请注意,使用file(GLOB)
构建源文件列表是个坏主意,CMake不鼓励这样做。原因很简单:添加源文件不会导致构建系统重新生成,这意味着不会拾取源文件。如果您明确地列出源文件,添加该文件意味着您必须将其添加到CMakeList中的列表中(或者包含在其中的文件中),这将触发重新生成构建系统。
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 ...