从 Cmake 创建 Xcode 项目包含不需要的编译器标志
Posted
技术标签:
【中文标题】从 Cmake 创建 Xcode 项目包含不需要的编译器标志【英文标题】:Creating Xcode project from Cmake contains unwanted compiler flags 【发布时间】:2016-05-31 15:45:33 【问题描述】:我一直无法找到明确的答案,所以如果有答案,我们深表歉意。
我使用 cmake 生成项目文件,因为我倾向于跨平台工作。在 OSX/Xcode 上,我看到正在使用不需要的编译器标志,特别是警告启用/禁用。我喜欢在编译时尽可能多地发出警告,并将警告设置为错误。
考虑以下几点:
文件:CMakeLists.txt
cmake_minimum_required( VERSION 3.0 )
project( test )
set( CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS -std=c++14 )
add_compile_options( "-Werror" )
add_compile_options( "-Weverything" )
add_compile_options( "-Wno-c++98-compat-pedantic" )
add_compile_options( "-Wno-padded" )
add_executable( Test main.cpp )
target_link_libraries( Test libstdc++.dylib libc++.dylib )
文件:main.cpp
#include <iostream>
int main( int argc, char * const argv[] )
(void)argc;
(void)argv;
std::cout << "Kittens." << std::endl;
return 0;
如果我再运行 cmake:
cmake -G Xcode .
(通常我会使用 builds 目录,但为了简单起见,这里没有)。
然后构建(从命令行):
cmake --build . --config Debug --target ALL_BUILD
简单示例将编译。如果我现在查看用于编译 main.cpp 的命令,我会看到以下内容:
CompileC test.build/Debug/Test.build/Objects-normal/x86_64/main.o main.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/username/Development/test
export LANG=en_US.US-ASCII
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c++ -arch x86_64 -fmessage-length=101 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -fcolor-diagnostics -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -DCMAKE_INTDIR=\"Debug\" -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -mmacosx-version-min=10.11 -g -Wno-sign-conversion -I/Users/username/Development/test/Debug/include -I/Users/username/Development/test/test.build/Debug/Test.build/DerivedSources/x86_64 -I/Users/username/Development/test/test.build/Debug/Test.build/DerivedSources -Wmost -Wno-four-char-constants -Wno-unknown-pragmas -F/Users/username/Development/test/Debug -std=c++14 -Werror -Weverything -Wno-c++98-compat-pedantic -Wno-padded -MMD -MT dependencies -MF /Users/username/Development/test/test.build/Debug/Test.build/Objects-normal/x86_64/main.d --serialize-diagnostics /Users/username/Development/test/test.build/Debug/Test.build/Objects-normal/x86_64/main.dia -c /Users/username/Development/test/main.cpp -o /Users/username/Development/test/test.build/Debug/Test.build/Objects-normal/x86_64/main.o
这里真正令人讨厌的是任何 -W 选项。 在我的 CMakeLists.txt 中,我明确表示我想要所有警告,将警告视为错误,并将几个警告列入白名单。
但是,如果我去掉编译命令中的所有 -W 选项,我会看到(除了我要求的):
-Wno-trigraphs
-Wno-missing-field-initializers
-Wno-missing-prototypes
-Wno-return-type
-Wno-non-virtual-dtor
-Wno-overloaded-virtual
-Wno-exit-time-destructors
-Wno-missing-braces
-Wparentheses
-Wswitch
-Wno-unused-function
-Wno-unused-label
-Wno-unused-parameter
-Wno-unused-variable
-Wunused-value
-Wno-empty-body
-Wno-uninitialized
-Wno-unknown-pragmas
-Wno-shadow
-Wno-four-char-constants
-Wno-conversion
-Wno-constant-conversion
-Wno-int-conversion
-Wno-bool-conversion
-Wno-enum-conversion
-Wno-shorten-64-to-32
-Wno-newline-eof
-Wno-c++11-extensions
-Winvalid-offsetof
-Wno-sign-conversion
-Wmost
-Wno-four-char-constants
-Wno-unknown-pragmas
列出的其中一些东西我真的不想禁用。我真的只想要我在 cmake 文件中指定的 -W 选项用于编译,但我看不到谁在注入所有这些额外的东西以及从哪里注入。
有什么方法可以让 cmake 告诉 xcode 不要在编译中包含所有这些额外的 -W 选项?
注意:使用:
cmake 3.5.2
Apple LLVM 版本 7.3.0 (clang-703.0.31)
【问题讨论】:
【参考方案1】:在project()
调用时,CMake 检测编译器(执行cmake
时您可能会看到相应的消息)并为其设置默认标志。这些标志存储在变量CMAKE_CXX_FLAGS
(通用)和CMAKE_CXX_FLAGS_<CONFIG>
(配置特定)中。
您可以根据需要修改这些变量:
1) 完全重写它们
set(CMAKE_CXX_FLAGS "<desired-value>")
2) 为它们附加新标志
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS <additional-flags>")
3) 从中删除特定值
string(REPLACE "<unwanted-flag>" "" CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS)
# or
string(REGEX REPLACE "<unwanted-flag-regex>" "" CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS)
等等。
【讨论】:
抱歉不够清楚,我已经检查过这种可能性。在项目调用下添加message( "CMAKE_CXX_FLAGS are " $CMAKE_CXX_FLAGS )
表明此时cmake 变量为空。所以没有什么可以替代的。同样,在我的测试中,CMAKE_CXX_FLAGS_DEBUG 仅包含“-g”。
嗯,查看构建命令行,似乎-g
之前的所有内容实际上都是一个编译器调用。您不太可能想要修改它。但是,如果您不想禁用某些警告,为什么不在CMAKE_CXX_FLAGS
中启用它们呢?例如,gcc 有 -Wall
选项,它可以同时启用许多警告。修改 CMAKE_CXX_FLAGS
是 CMake 中启用您想要的功能的常用方法。
事实上,如果将以下内容添加到脚本中:get_cmake_property(_variableNames VARIABLES) foreach (_variableName $_variableNames) message(STATUS "$_variableName=$$_variableName") endforeach()
我在构建命令行上看到的任何额外警告参数都不会包含在任何 cmake 变量中。就此而言,我通过add_compile_options
添加的也不是。
编译器调用可能是 XCode 生成器 的一部分,生成器可能会使用一些不会通过 CMake 变量显示的内部内容。至于add_compile_options,它修改的是目录属性 COMPILE_OPTIONS
,而不是变量。
我所寻求的解决方案是拥有一个单独打开所有警告的头文件,然后将我接受的那些列入白名单。该头文件通过命令行选项 (-include) 包含在内。谢天谢地,我现在看到了一些我希望看到的警告!见:github以上是关于从 Cmake 创建 Xcode 项目包含不需要的编译器标志的主要内容,如果未能解决你的问题,请参考以下文章
如何让 CMake 创建一个 xcode 项目,其中警告在系统标头中被抑制?