【发布时间】:2018-12-17 07:42:40
【问题描述】:
如果我编译 C++ 程序 /tmp/src/main.cc
#include <iostream>
int main() {
#ifdef demo1
std::cout << "Output from demo1\n";
#endif
#ifdef demo2
std::cout << "Output from demo2\n";
#endif
}
使用文件 /tmp/src/CMakeLists.txt
中的构建说明cmake_minimum_required(VERSION 3.11)
project(test_save_temps LANGUAGES CXX)
function(my_add_executable name)
add_executable(${name})
target_sources(${name} PRIVATE main.cc)
# target_compile_options(${name} PRIVATE --save-temps)
target_compile_definitions(${name} PRIVATE
${name}
)
endfunction()
my_add_executable(demo1)
my_add_executable(demo2)
一切正常。
ubuntu@laptop:/tmp$ mkdir /tmp/build
ubuntu@laptop:/tmp$ cd /tmp/build
ubuntu@laptop:/tmp/build$ cmake -G Ninja /tmp/src
-- The CXX compiler identification is GNU 8.2.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
ubuntu@laptop:/tmp/build$ ninja
[4/4] Linking CXX executable demo1
ubuntu@laptop:/tmp/build$ ls
build.ninja CMakeCache.txt CMakeFiles cmake_install.cmake demo1 demo2 rules.ninja
ubuntu@laptop:/tmp/build$ ./demo1
Output from demo1
ubuntu@laptop:/tmp/build$ ./demo2
Output from demo2
ubuntu@laptop:/tmp/build$
但如果我从文件 /tmp/src/CMakeLists.txt 中删除注释 激活线路
target_compile_options(${name} PRIVATE --save-temps)
做同样的事情
ubuntu@laptop:/tmp$ mkdir /tmp/build_with_save_temps
ubuntu@laptop:/tmp$ cd /tmp/build_with_save_temps
ubuntu@laptop:/tmp/build_with_save_temps$ cmake -G Ninja /tmp/src
-- The CXX compiler identification is GNU 8.2.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build_with_save_temps
ubuntu@laptop:/tmp/build_with_save_temps$ ninja
[4/4] Linking CXX executable demo1
ubuntu@laptop:/tmp/build_with_save_temps$ ls
build.ninja CMakeCache.txt CMakeFiles cmake_install.cmake demo1 demo2 main.ii main.s rules.ninja
ubuntu@laptop:/tmp/build_with_save_temps$ ./demo1
Output from demo1
ubuntu@laptop:/tmp/build_with_save_temps$ ./demo2
Output from demo1
ubuntu@laptop:/tmp/build_with_save_temps$ find . -name '*.s'
./main.s
ubuntu@laptop:/tmp/build_with_save_temps$
程序demo2的输出不正确。
我希望在构建目录中找到两个版本的程序集文件main.s。
在这里我提供一些关于我的计算机系统的额外信息
- cmake 3.13.2
- g++ 8.2.0
- 忍者 1.8.2
- Ubuntu 18.10
如何修改 /tmp/src/CMakeLists.txt 以保留两个版本的程序集文件 main.s?
更新解决方案:
当我按照用户 fritzone 的答案 https://stackoverflow.com/a/53811064/757777 中的建议使用 -save-temps=obj 时,一切都开始工作了。
我换了
target_compile_options(${name} PRIVATE --save-temps)
与
target_compile_options(${name} PRIVATE -save-temps=obj)
现在我得到了两个汇编文件
ubuntu@laptop:/tmp/build2$ find . -name '*.s'
./CMakeFiles/demo2.dir/main.cc.s
./CMakeFiles/demo1.dir/main.cc.s
ubuntu@laptop:/tmp/build2$
并且可执行文件 demo1 和 demo2 按预期工作
ubuntu@laptop:/tmp/build2$ ./demo1
Output from demo1
ubuntu@laptop:/tmp/build2$ ./demo2
Output from demo2
ubuntu@laptop:/tmp/build2$
【问题讨论】:
-
我会尝试使程序集输出名称依赖于目标配置。我相信这应该可以通过 CMake 实现,尽管我手头没有现成的收据。 (在我们的例子中,出于“历史”原因,我们使用
-d为调试的库和可执行文件添加后缀,尽管由于单独的构建输出目录实际上没有必要。)