一、背景
我们需要在项目中构建一个测试模块,但是生成的可执行程序,并没有输出到我们想要的项目out
目录中,而生成一个单独的命令,试了很多CMAKE
的宏都没生效,结果发现是一个project
引发的血案…
二、目录结构
其中SonProject
是我们添加的模块:其中的CMakeLists
是这样写的:
#设置cmake的最低版本
cmake_minimum_required(VERSION 3.10)
# 设置工程的名称
project(myproject)
#将源代码添加到工程
add_executable(myproject main.cpp)
结果生成的可执行文件并不在我们想要的x64-debug
中:
使用:set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${IDE_BIN_DIR})
也没有生效。
三、破案
去掉CmakeLists
中的project(myproject)
加: set(EXECUTABLE_OUTPUT_PATH${CMAKE_BINARY_DIR}/${IDE_BIN_DIR})
#设置cmake的最低版本
cmake_minimum_required(VERSION 3.10)
#设置可输出路径
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${IDE_BIN_DIR})
#将源代码添加到工程
add_executable(myproject main.cpp)
四:关于Project关键字
五、知识扩充
CMake
中的 add_subdirectory
命令可以让你将一个子目录作为另一个 project
的一部分来构建。这意味着,如果你在使用 add_subdirectory
命令时,将库生成到子目录而不是 x64-Debug
目录,那么这个库的构建目录将会是所有在父目录中的项目构建目录下的一个子目录。
例如,假设你有一个包含两个子目录的项目,分别为 lib
和 app
,然后你在主目录中使用了以下命令:
add_subdirectory(lib)
add_subdirectory(app)
假设 lib
子目录中有一个名为 mylib
的库,而在 lib/CMakeLists.txt
文件中,你定义了一个名为 mylib
的目标,如下所示:
add_library(mylib SHARED mylib.cpp)
然后你再次在 app/CMakeLists.txt
文件中使用了以下命令:
target_link_libraries(myapp mylib)
在这个例子中,当你运行 CMake
并构建 app
应用程序时,生成的 myapp
可执行文件将会被构建到 app/build
目录中。而 mylib
库将会被构建到 lib/build
目录下的子目录中。这是因为 CMake
会在父目录的构建目录下为每个子目录创建一个新的构建目录。
值得注意的是,无论在何处指定生成的库文件的位置,最终都是由 CMake
和编译器来确定生成的库文件的位置。在多个目标之间可能有一些差异。例如,生成的库文件的实际位置可能取决于您在将目标链接到库时的命令行参数。
在 CMake
中,默认情况下,每个子目录都会创建一个新的构建目录。如果你不想让 CMake
在父目录的构建目录下为每个子目录创建一个新的构建目录,你可以在父目录的 CMakeLists.txt
文件中设置 CMAKE_SKIP_BUILD_RPATH
变量为 TRUE
。
以下是一个简单的示例:
# CMakeLists.txt in top-level directory
cmake_minimum_required(VERSION 3.0)
project(MyProject)
# Set CMAKE_SKIP_BUILD_RPATH to TRUE
set(CMAKE_SKIP_BUILD_RPATH TRUE)
# Add subdirectories
add_subdirectory(MyLibrary)
add_subdirectory(MyExecutable)
在这个示例中,我们在顶层 CMakeLists.txt
文件中设置了 CMAKE_SKIP_BUILD_RPATH
变量为 TRUE
,这将阻止 CMake
在父目录的构建目录下为每个子目录创建一个新的构建目录。
请注意,如果你使用了外部构建目录,那么 CMAKE_SKIP_BUILD_RPATH
变量将不起作用。在这种情况下,你需要手动为每个子目录创建一个新的构建目录,并在构建时指定正确的路径。