为何自定义CMAKE_BINARY_DIR在子目录中丢失/bin后缀?
为什么CMAKE_BINARY_DIR的/bin后缀在子目录中消失?
这是因为你误解了CMAKE_BINARY_DIR这个变量的本质——它是CMake的内置全局变量,专门用来指向当前正在处理的CMakeLists.txt对应的构建目录根,你不应该手动修改它的值。
具体原因:
- 当你在顶层CMakeLists.txt里强行用
set(CMAKE_BINARY_DIR ...)覆盖它时,这个修改只在当前的顶层CMake上下文里生效。 - 当执行
add_subdirectory进入子目录后,CMake会自动重新计算CMAKE_BINARY_DIR的值,将其设置为子目录对应的构建目录根(你的输出显示为/home/me/myproj/cmakebuild,说明你大概率是直接在cmakebuild目录下运行的cmake命令,此时子目录的构建目录根会回退到主构建目录)。 - 手动修改
CMAKE_BINARY_DIR会干扰CMake的内部构建目录管理逻辑,导致子目录中变量值不符合你的预期。
正确的做法:
如果你想指定可执行文件的输出目录,应该使用CMake专门提供的变量CMAKE_RUNTIME_OUTPUT_DIRECTORY,而不是修改CMAKE_BINARY_DIR。修改你的顶层CMakeLists.txt如下:
# 设置可执行文件输出到指定的bin目录 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/cmakebuild/bin) MESSAGE("Executable output dir: \n${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ") add_subdirectory("sub/subA")
然后在子目录的CMakeLists.txt里,你可以正常使用这个变量,它会被正确传递:
MESSAGE("SUBDIR Executable output dir: \n${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ")
这样无论在顶层还是子目录,这个变量都会保持一致,而且不会干扰CMake的内部构建目录管理。
另外补充一点:如果你确实需要自定义构建目录的结构,建议在运行cmake命令时通过-B参数指定构建目录,比如:
cmake -S . -B cmakebuild/bin
这种方式是CMake推荐的标准做法,比手动修改内置变量更可靠。
内容的提问来源于stack exchange,提问作者PizzaBeer
相关产品推荐
相关产品推荐

