如何使用CMake为项目(而不是整个解决方案)设置警告级别?应该在Visual Studio和GCC上工作.
我找到了各种选项,但大多数似乎不工作或与文档不一致.
在Unix中,我可以运行myscript '"test"',我会得到"test".
在Windows中,cmd我得到了'test'.
如何将双引号作为参数传递?我想知道如何从cmd窗口手动执行此操作,因此我不必编写程序来测试我的程序.
我尝试在CMake的命令行中设置预处理器宏.我试过了:
set generator="Visual Studio 8 2005"
set params=-D MY_MACRO=1
cmake.exe -G %generator% %params% ..\some_project
Run Code Online (Sandbox Code Playgroud)
但是我在编译时既没有定义,也没有MY_MACRO在CMake生成的文件中找到该名称,除了CMakeCache.txt它在表单中的位置:
MY_MACRO:UNINITIALIZED=1
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
Visual Studio 2017提供完整的CMake集成.要了解这个组合,我从这个基本样本开始:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)
Run Code Online (Sandbox Code Playgroud)
和
// foo.cpp
int main() {}
Run Code Online (Sandbox Code Playgroud)
这正确地生成了构建脚本,并且编译和链接没有任何问题.那很简单.
另一方面,试图设置编译器选项,结果却是微不足道的.在我的情况下,我试图将警告级别设置为4.
明显的解决方案
add_compile_options("/W4")
Run Code Online (Sandbox Code Playgroud)
没有像预期的那样平息.传递给编译器的命令行现在既包含/W4(按预期),也包含/W3(从其他地方获取),产生以下警告:
Run Code Online (Sandbox Code Playgroud)cl : Command line warning D9025: overriding '/W3' with '/W4'
要解决这个问题,我需要替换任何不兼容的编译器选项,而不是只添加一个.CMake没有为此提供任何直接支持,标准解决方案(正如此问答所示)似乎是:
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
Run Code Online (Sandbox Code Playgroud)
然而,这有两个问题:
CMAKE_CXX_FLAGS,适用于所有C++目标.这可能不是有意的(现在对我来说不是问题).我的问题是双重的:
/Wall选项,这也是不兼容的/W4. 亲爱的C++编程员,
在使用Visual Studio工具链在Windows上构建一段时间后,我决定给Clang 5一个镜头.
我安装了LLVM 5.0.0二进制文件,Ninja构建环境,VS 2017工具和CMake 3.9.3.最终目标是能够使用VS Code编译C和C++应用程序,将CMake集成为"IDE",将Clang与LLD一起编译为编译器和链接器.
一个简单程序的编译和执行工作得非常好(相应终端历史的屏幕截图).Clang在VS Tools目录中自动检测到Windows的标准lib,并生成了可执行输出.
下一步是使用Ninja建立一个简单的构建(ninja.build文件和终端历史的截图).构建过程按预期工作,并像以前一样生成可运行的可执行文件.
当我开始将CMake集成到流程中时,问题就开始了.我的期望是CMake生成一个ninja构建文件并运行它,对吗?我尝试了以下CMakeLists文件
cmake_minimum_required(VERSION 3.9)
project(Test)
add_executable(Test main.c)
Run Code Online (Sandbox Code Playgroud)
并称为CMake cmake -G Ninja.由此产生的结果是令人失望的,我不明白,分别自己解决问题.
-- The C compiler identification is Clang 5.0.0
-- The CXX compiler identification is Clang 5.0.0
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe -- broken
CMake Error at C:/Meine_Programme/CMake/share/cmake-3.9/Modules/CMakeTestCCompiler.cmake:51 (message):
The C compiler "C:/Meine_Programme/LLVM/bin/clang.exe" is not able to
compile a simple test program.
It fails with …Run Code Online (Sandbox Code Playgroud) 我想改变的默认值CMAKE_CXX_FLAGS_RELEASE或CMAKE_CXX_FLAGS_DEBUG在CMake的.基本上,我有一些项目默认值与CMake略有不同(例如发布),我不应该问自己"哦,当添加add_compile_options时,他们的-O3或我们的-O2优先."
现在,我知道如何设置这些值,但我不知道如何使用户可以通过两种常用方式进行编辑:DCMAKE_CXX_FLAGS_DEBUG=yourflags在命令行上使用 - 或者使用ccmake或CMakeSetup配置它.
问题是CMAKE为这些设置和缓存它们自己的默认值,如果你试图在不使用FORCE的情况下覆盖变量,那么"默认值"永远不会改变.如果我在set命令中使用FORCE:set(CMAKE_CXX_FLAGS_DEBUG blah CACHE STRING "" FORCE)它会在每次运行脚本时覆盖它,从而消除了用户根据需要进行更改的可能性.
我设法通过执行以下操作来破解它与CCMAKE一起工作,但是这仍然不起作用,cmake -DCMAKE_CXX_FLAGS_DEBUG因为它覆盖用户更改后完成它:
set(DEFAULTS_SET FALSE CACHE BOOL "")
set(CMAKE_CXX_FLAGS_DEBUG "-this -that" CACHE STRING "" FORCE)
set(DEFAULTS_SET TRUE CACHE BOOL "" FORCE)
Run Code Online (Sandbox Code Playgroud)
显然,这是一个讨厌的黑客,并没有完全工作(在cmake -Dwhatever = thisorthat的情况下).我也可以添加其他构建类型,但我真的不明白为什么只需更改一些简单的东西就是必要的.
编辑2015年3月1日:
我已经创建了一个有效的解决方案,尽管我仍然对我必须做的事情感到非常激动.我看到其他评论解决了设置CMAKE_CXX_FLAGS_DEBUG和朋友的问题而没有让他们受到破坏,但这最初对我不起作用,因为我试图根据正在使用的编译器选择它们.但是,在它已经为我填充变量之前,编译器尚未确定.我使用的技巧如下.您必须在项目命令之前将flags变量设置为'special'.
set(CMAKE_CXX_FLAGS_DEBUG "_UNSET" CACHE STRING "")
project(your_project C CXX)
if(${CMAKE_CXX_FLAGS_DEBUG} STREQUAL "_UNSET")
# Do some compiler switching here and then set your flags with FORCE.
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "" FORCE)
endif() …Run Code Online (Sandbox Code Playgroud) 我无法更改我所从事的项目的 CMakeLists.txt,并且其中使用的 cmake 工具链文件仅声明要发布的 C 和 CXX FLAGS。
因此,为了调试,我需要强制使用自己的标志(即将 -O0 -DDEBUG 附加到 CFLAGS 和 CXXFLAGS)。
所以我尝试使用以下示例通过 cli
主要.cpp:
#include <iostream>
int main(int argc, char * argv[])
{
std::cout << "hello world\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#prescon settings
project(cmakecflags)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CXX_EXTENSIONS NO)
enable_testing()
add_executable(cmakecflagsapp
main.cpp
)
message(CFLAGS=${CFLAGS})
message(CXXFLAGS=${CXXFLAGS})
Run Code Online (Sandbox Code Playgroud)
调用cmake:
CFLAGS=' -O0 -DDEBUG ' CXXFLAGS=' -O0 -DDEBUG ' cmake -G 'Unix Makefiles' -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Debug .
Run Code Online (Sandbox Code Playgroud)
结果如预期,使 2 个变量为空
-- The C compiler identification …Run Code Online (Sandbox Code Playgroud) 我想在我的 x64 Windows 计算机上构建 x86 Windows 应用程序。
\n\n我使用 CMake、Ninja、clang-cl、lld-link 和 VS Build Tools 2017 以及以下 CMakeLists
\n\ncmake_minimum_required(VERSION 3.9)\nproject(Test CXX)\n\nadd_library(TestLib STATIC "")\ntarget_include_directories(TestLib\n PUBLIC\nTestLib/inc\n)\ntarget_sources(TestLib\n PRIVATE\n TestLib/src/Flop.cpp\n TestLib/src/testClass.cpp\n)\n\nadd_executable(Test "")\ntarget_sources(Test\n PRIVATE\n src/main.cpp\n)\ntarget_link_libraries(Test\n TestLib\n)\nRun Code Online (Sandbox Code Playgroud)\n\n我的设置适用于 x64 应用程序。我初始化构建环境并vcvars64调用 cmake
cmake -G Ninja -DCMAKE_CXX_COMPILER:PATH="C:\\MeineProgramme\\LLVM\\bin\\clang-cl.exe" -DCMAKE_LINKER:PATH="C:\\MeineProgramme\\LLVM\\bin\\lld-link.exe"\nRun Code Online (Sandbox Code Playgroud)\n\n这会产生完美的忍者构建文件并生成功能性可执行文件。
\n\n如果我想构建 x86 应用程序,CMake 无法检测构建环境。vcvars32我使用或初始化构建环境,vcvarsamd64_x86并使用与上面相同的命令来调用 CMake。这会导致在检测构建环境期间出现错误。
CMake错误日志有以下内容
\n\nCompiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" failed.\nCompiler: C:/MeineProgramme/LLVM/bin/clang-cl.exe \nBuild flags: \nId flags: \n\nThe output was:\n1120\nLINK : error LNK2001: Nicht …Run Code Online (Sandbox Code Playgroud) 我在C ++ 14项目中使用CMake 3.8.2,GNU make 4.2.1和GCC 6.4.0,在构建时我注意到了一个奇怪的行为。我使用CMake在名为“ build”的子文件夹中进行源代码外构建,cmake ..然后运行make。
CMake运行良好,没有任何错误,make会像我期望的那样构建所有源文件,直到完成编译并开始链接它们为止。然后它将失败并显示错误
[ 83%] ...
[100%] Linking CXX executable myproject
/usr/bin/ld: some-source-file.cc.o: undefined reference to symbol '_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21'
Run Code Online (Sandbox Code Playgroud)
有趣的是,到目前为止,它不显示任何编译器警告,而仅显示上述链接器错误。
现在,当我忽略该错误并简单地运行cmake ..,然后make再次运行(就像我之前所做的那样)时,即使我没有更改任何代码或与CMake相关的文件,我也会得到我的代码应产生的所有编译器警告,并且所有链接都可以正常运行同时。
我可以build通过运行删除目录中的所有文件来重现此行为rm -r *。
这是我的CMakeLists.txt文件:
# Define minimum required CMake version
cmake_minimum_required(VERSION 3.8.2)
# Setting compiler related settings
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -O2 -lstdc++")
set(CMAKE_CXX_STANDARD 14)
# Define project name
project(MyProject)
# Find source files
file(GLOB_RECURSE …Run Code Online (Sandbox Code Playgroud) 我正在编写一些可以编译为 C++ 或 CUDA 的代码。在后一种情况下,它使用 CUDA 内核,在前一种情况下,它只运行常规代码。
创建了一个名为 test.cpp 的文件后,我可以手动编译它:
g++ test.cpp # build as C++ with GCC
nvcc -x cu test.cpp # build as CUDA with NVCC
Run Code Online (Sandbox Code Playgroud)
在哪里 -x cu告诉 nvcc 虽然它是一个 .cpp 扩展名,但我希望它把它当作 CUDA。到现在为止还挺好。
但是,当我迁移到使用 CMake 时,我不知道如何做同样的事情。即:如何要求 CMake 使用 NVCC 而不是 GCC 编译 .cpp 文件。
cmake_minimum_required(VERSION 3.9)
project(cuda_test LANGUAGES CUDA CXX)
add_executable(cuda_test test.cpp) # builds with GCC
Run Code Online (Sandbox Code Playgroud)
如果我创建指向原始文件的符号链接:
cmake_minimum_required(VERSION 3.9)
project(cuda_test LANGUAGES CUDA CXX)
add_executable(cuda_test test.cpp) # builds with GCC
Run Code Online (Sandbox Code Playgroud)
然后更改 CMakeLists.txt:
add_executable(cuda_test test.cu) # builds with …Run Code Online (Sandbox Code Playgroud)