我问这个是下次我使用CMake的时候提醒自己的.它永远不会坚持,谷歌的结果也不是很好.
在CMake中设置和使用变量的语法是什么?
我想使用一组全局标志来编译项目,这意味着在我指定的顶级CMakeLists.txt文件中:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Run Code Online (Sandbox Code Playgroud)
但是,对于一个子目录中的特定文件(假设为"foo.cpp"),我想将编译标志切换为不应用-Weffc ++(包含的商业库我无法更改).为了简化只使用-Wall的情况,我试过:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
Run Code Online (Sandbox Code Playgroud)
,这没用.我也试过了
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
Run Code Online (Sandbox Code Playgroud)
和
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
Run Code Online (Sandbox Code Playgroud)
,其中既没有奏效.
最后,我尝试删除这个定义:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
Run Code Online (Sandbox Code Playgroud)
,这也没有用(意思是,我得到了很多关于商业图书馆的风格警告).(**注意:如果在构建可执行文件后不重新包含-Weffc ++指令,则会禁止警告.)
我也试过暂时删除编译标志:http: //www.cmake.org/pipermail/cmake/2007-June/014614.html ,但这没有帮助.
对此没有优雅的解决方案吗?
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. 我有以下 CMake 文件:
project(MyLib)
cmake_minimum_required(VERSION 2.8)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
set(ROOT_DIR ${CMAKE_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(MAIN_LIBRARY_NAME "mylib")
add_subdirectory(src)
add_subdirectory(test_app)
add_subdirectory(test_app1) <--- I want to disable -Werror flag for CMakeLists.txt in this folder.
add_subdirectory(test_app2)
Run Code Online (Sandbox Code Playgroud)
如何禁用子目录之一的 -Werror 标志?在每个子目录中,我也有 CMakeLists.txt。
在其他地方有人问过这样的问题:“如何关闭一个文件的优化?” 答案通常是这样的:
cmake_minimum_required( VERSION 3.8 )
project( Hello )
add_executable( hello hello.c foo.c bar.c )
set( CMAKE_C_FLAGS_RELEASE "" )
set( CMAKE_CXX_FLAGS_RELEASE "" )
set_source_files_properties( hello.c
PROPERTIES
COMPILE_FLAGS -O0 )
Run Code Online (Sandbox Code Playgroud)
除非您像这样调用 cmake,否则这将有效:
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../hello
Run Code Online (Sandbox Code Playgroud)
你在你的build.ninja
FLAGS = -O3 -DNDEBUG -O0
Run Code Online (Sandbox Code Playgroud)
编译此源文件时要添加的其他标志。
这是有道理的,它被添加到 COMPILE_FLAGS 列表中,它不会覆盖现有的编译器标志。
那么,在 CMake 中如何覆盖单个文件的优化级别并能够编译项目的其余部分Release?否则,您可以强制编译为CMAKE_BUILD_TYPE=""默认行为,但这在某种程度上违背了 Cmake 的卖点。
我想将链接器标志传递给项目中的所有子项目(子目录CMakeList)。
在切换到新的cmake 3.3之前,我使用了运行良好的以下代码(cmake 3.2),为编译和链接添加了标志:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -stdlibc++")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -stdlibc++")
Run Code Online (Sandbox Code Playgroud)
在cmake 3.3中,它不再起作用,并且仅在编译步骤设置标志。我更新了CMakeList以使用更“现代”的cmake语法:
set(MY_DEBUG_OPTIONS -g -stdlib=libstdc++ -Wfatal-errors)
set(MY_RELEASE_OPTIONS -O3 -stdlib=libstdc++ -Wfatal-errors)
add_compile_options(
"$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>"
"$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
Run Code Online (Sandbox Code Playgroud)
这为所有子项目设置了编译标志,是否对链接程序标志采取了类似的方法?我知道可以使用target_link_libraries命令在目标基础上添加链接器标志,但找不到其他任何东西。
我尝试使用CMAKE_SHARED_LINKER_FLAGS变量(以及exe,模块等对应的var)没有成功。
更新:
事实证明,这与cmake版本无关CMAKE_CXX_FLAGS_XXX,除了第一个make命令外,变量都可以正常工作。如果make第二次运行(在CmakeList中进行了修改),则会显示标志。
我想我在使用简单的CMakeList进行测试时找到了一个解决方案:如果在project命令后声明了标志,它就可以按预期工作。我不知道这是cmake本身的要求,还是只是怪异的行为。
cmake_minimum_required (VERSION 3.2)
set(PROJECT Test_Project)
# Not working (on first run)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -stdlib=libstdc++ -Wfatal-errors")
project(${PROJECT})
# Declare here instead...
add_executable(Test test.cpp)
MESSAGE( STATUS "Config flags : " ${CMAKE_CXX_FLAGS_RELEASE})
Run Code Online (Sandbox Code Playgroud)
使用:
cmake …Run Code Online (Sandbox Code Playgroud) 要使值从子目录中可用于整个CMake环境,可以使用set(VARIABLE_NAME Value CACHE INTERNAL "")语法设置缓存变量或使用语法设置全局属性set_property(GLOBAL PROPERTY VARIABLE_NAME Value)(另请参阅关于CMake中变量的非常好的答案).
使用后者的优点是,您不会为CMake缓存"污染"它未设计的内容,并且在不使用FORCE参数时您不依赖于被删除的缓存.
但是使用变量值的语法不是用户友好的,因为您必须使用get_property而不是简单地使用${...}表示法来检索值.
是否有更简单的语法来代替get_property(某种语法糖)?
我有一个cmake项目,其中包含许多cpp文件(大约400多个),并且使用/ MP(多线程)编译器选项可以在具有多个内核的CPU上显着加快编译速度。
问题是,每次我使用CMake重新生成解决方案文件时,该选项都被禁用,导致编译非常慢。我可以通过在Visual Studio中手动更改每个单个项目(解决方案包含许多不同项目)的选项来解决此问题。但是,每次我通过运行CMake重新生成解决方案文件时(例如,当我git pull别人的更改来添加/删除一些文件时),此更改就会被覆盖。
我如何使其具有持久性,以便CMake始终在VS项目内部启用多线程编译?
我们CMakeList.txt有一个target_include_directories在蠕动.它打破了我们的下级客户端,如Ubuntu LTS,CentOS的和Solaris.
我知道我可以用以下内容来保护它(感谢ZW),但我需要Cmake版本2.8.11及更早版本(???)的内容.
cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR)
...
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
target_include_directories(...)
else()
???
endif()
Run Code Online (Sandbox Code Playgroud)
我们的目录结构非常简单.有一个目录中包含头文件,同一目录中包含源文件.这是设计使用户在调试器下没有麻烦.
给出我们的配置可以使用以下内容(如果@steveire答案适用于我们,我不清楚):
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
target_include_directories(...)
else()
include_directories("${ROOT_SOURCE_DIR}")
endif()
Run Code Online (Sandbox Code Playgroud)
如果没有,应该用什么代替target_include_directories2.8.11及更早版本?
此答案描述了如何从头开始创建自定义配置类型。如何制作与 builtin 完全匹配的配置类型Release,仅添加一些标志?我现在正在使用这个:
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;ReleaseWithAssertions" CACHE STRING
"Available build-types: Debug, Release and ReleaseWithAssertions")
set(CMAKE_CXX_FLAGS_RELEASEWITHASSERTIONS "${CMAKE_CXX_FLAGS_RELEASE}
-DENABLE_ASSERTIONS=1")
Run Code Online (Sandbox Code Playgroud)
这似乎是我想要的,但我只是复制 的值CMAKE_CXX_FLAGS_RELEASE,所以我想知道是否有用户可能期望的我遗漏的东西?
我试图使用带有add_compile_options的以下编译选项的cmake: add_compile_options(-pipe -O2 -std=c++98 -W -Wall -pedantic)
但是它似乎并没有在编译过程中实际使用。
make -n | grep pedantic 不返回任何东西
仅供参考,我的cmake命令及其返回内容:
cmake -G"Unix Makefiles" -DARCH:STRING=x86 -Bosef -H. -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
-- The C compiler identification is GNU 4.8.3
-- The CXX compiler identification is GNU 4.8.3
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++
-- Check for working …Run Code Online (Sandbox Code Playgroud) cmake ×12
c++ ×3
c ×1
dry ×1
g++ ×1
idioms ×1
linker ×1
properties ×1
versioning ×1
visual-c++ ×1