我知道如何使用cmake命令传递编译器选项
set(CMAKE_CXX_FLAGS "-Wall -Wno-dev -Wl,-rpath=/home/abcd/libs/")
是否还有任何方法可以从命令行传递选项,这将覆盖CMakeList.txt选项,如 -
cmake -Wl,-rpath=/home/abcd/newlibs/ path/to/CMakeLists.txt
或
cmake -D CMAKE_CXX_FLAGS="-Wno-dev -Wl,-rpath=/home/abcd/libs/" path/to/CMakeLists.txt
我的主要问题是我想知道如何附加标志以及如何从命令行覆盖现有的编译器标志。
答案 0 :(得分:21)
是的,您可以附加编译器和链接器选项。但是你需要在CMake中区分两件事:第一次调用生成构建环境,以及在更改CMakeList.txt
文件或依赖项后重新生成构建环境的所有连续调用。
以下是一些可能性(不包括更复杂的toolchain变体):
缓存的CMAKE_CXX_FLAGS
变量的初始内容是在OS /工具链检测期间由CMake自身设置的CMAKE_CXX_FLAGS_INIT
和CXXFLAGS
环境变量中设置的内容的组合。所以你最初可以打电话:
cmake -E env CXXFLAGS="-Wall" cmake ..
稍后CMake会期望用户直接修改CMAKE_CXX_FLAGS
缓存变量以附加内容,例如使用像ccmake
提交的编辑器与CMake一起使用。
您可以轻松地引入自己的构建类型,例如ALL_WARNINGS
。附加构建类型特定部分:
cmake -DCMAKE_CXX_FLAGS_ALL_WARNINGS:STRING="-Wall" -DCMAKE_BUILD_TYPE=ALL_WARNINGS ..
链接器选项或多或少等同于编译器选项。只是CMake的变量名称取决于目标类型(EXE
,SHARED
或MODULE
)。
CMAKE_EXE_LINKER_FLAGS_INIT
,CMAKE_SHARED_LINKER_FLAGS_INIT
或CMAKE_MODULE_LINKER_FLAGS_INIT
确实与环境变量LDFLAGS
合并为CMAKE_EXE_LINKER_FLAGS
,CMAKE_SHARED_LINKER_FLAGS
和{{ 3}}
所以你可以打电话:
cmake -E env LDFLAGS="-rpath=/home/abcd/libs/" cmake ..
见上文。
附加构建类型特定部分:
cmake -DCMAKE_SHARED_LINKER_FLAGS_MY_RPATH:STRING="-rpath=/home/abcd/libs/" -DCMAKE_BUILD_TYPE=MY_RPATH ..
请注意,CMake确实提供了特殊的变量来以独立于平台的方式设置编译器/链接器标志。因此,您不需要知道特定的编译器/链接器选项。
以下是一些例子:
不幸的是,编译器的警告级别(CMAKE_INSTALL_RPATH_USE_LINK_PATH
)
答案 1 :(得分:3)
cmake -D CMAKE_CXX_FLAGS="-Wno-dev -Wl,-rpath=/home/abcd/libs/" path/to/CMakeLists.txt
这应该可行,问题是如果你find_package()一些包也改变了CMAKE_CXX_FLAGS,那么它不仅会部分工作。
答案 2 :(得分:2)
我的答案旨在证明一件事:
CMAKE_C_FLAGS
和CMAKE_CXX_FLAGS
之类的命令行选项始终附加,并且永远不会覆盖。
来了。
hello_world
下的文件hello.c
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("Hello World!\n");
#ifdef DEFINED_IN_CMAKELISTS
printf("You are here because you defined DEFINED_IN_CMAKELISTS in CMakeLists and it is not overwritten.\n");
#else
printf("You are here because CLI CMAKE_C_FLAGS overwrote DEFINED_IN_CMAKELISTS, or you have NOT defined DEFINED_IN_CMAKELISTS.\n");
#endif
#ifdef DEFINED_IN_CLI
printf("You are here because you defined DEFINED_IN_CLI when running cmake -DCMAKE_C_FLAGS.\n");
#else
printf("You are here because you have NOT defined DEFINED_IN_CLI when running cmake -DCMAKE_C_FLAGS.\n");
#endif // #ifdef DEFINED_IN_CLI
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1 FATAL_ERROR)
project(Hello)
set(HELLO_SRCS Hello.c)
add_executable(Hello ${HELLO_SRCS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEFINED_IN_CMAKELISTS")
$ mkdir _build && cd _build && cmake ..
-- The C compiler identification is AppleClang 11.0.3.11030032
-- The CXX compiler identification is AppleClang 11.0.3.11030032
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/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: /Users/me/Desktop/_dev/playground/cmake/hello_world/_build
$ make
Scanning dependencies of target Hello
[ 50%] Building C object CMakeFiles/Hello.dir/Hello.c.o
[100%] Linking C executable Hello
[100%] Built target Hello
$ ./Hello
Hello World!
You are here because you defined DEFINED_IN_CMAKELISTS in CMakeLists and it is not overwritten.
You are here because you have NOT defined DEFINED_IN_CLI when running cmake -DCMAKE_C_FLAGS.
$ cmake -DCMAKE_C_FLAGS="-DDEFINED_IN_CLI" ..
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/me/Desktop/_dev/playground/cmake/hello_world/_build
$ make
[ 50%] Building C object CMakeFiles/Hello.dir/Hello.c.o
[100%] Linking C executable Hello
[100%] Built target Hello
$ ./Hello
Hello World!
You are here because you defined DEFINED_IN_CMAKELISTS in CMakeLists and it is not overwritten.
You are here because you defined DEFINED_IN_CLI when running cmake -DCMAKE_C_FLAGS.
从上面的测试中,您可以看到,即使没有硬性地使用类似的东西
-DCMAKE_C_FLAGS="${CMAKE_C_FLAGS} -DDEFINED_IN_CLI"
,CMake仍会将CLI选项附加到CMakeLists.txt
中。
答案 3 :(得分:1)
也许这行得通-
cmake -DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS) -DYOUR_CUSTOM_DEFINE=1" <rest of original cmake cmdline>
就像上面提到的Tomaz一样。 -m
答案 4 :(得分:0)
这里的大多数答案都是有效的,但是我也偶然发现如何通过
CMAKE_CXX_FLAGS
并添加包含目录的目录(在Windows中)。
显然,如果您从命令行运行该参数-您需要格外小心加引号(另请参见here)
cmake ... -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows -X -I """C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um""" "
因此,如果include路径包含空格,则需要将其引号,但您还需要引号CMAKE_CXX_FLAGS
,最后以单引号("
)引号开始,无论何时,需要引用-您放置三个引号字符来代替。 ("""
)
总体来说有点奇怪。花了一段时间才能弄清楚。