相关疑难解决方法(0)

设置和使用变量的CMake语法是什么?

我问这个是下次我使用CMake的时候提醒自己的.它永远不会坚持,谷歌的结果也不是很好.

在CMake中设置和使用变量的语法是什么?

cmake

143
推荐指数
3
解决办法
11万
查看次数

覆盖单个文件的编译标志

我想使用一组全局标志来编译项目,这意味着在我指定的顶级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 ,但这没有帮助.

对此没有优雅的解决方案吗?

c++ cmake compiler-warnings

95
推荐指数
2
解决办法
6万
查看次数

如何在Visual Studio 2017中使用CMake设置编译器选项

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(从其他地方获取),产生以下警告:

cl : Command line warning D9025: overriding '/W3' with '/W4'
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,我需要替换任何不兼容的编译器选项,而不是只添加一个.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++目标.这可能不是有意的(现在对我来说不是问题).
  • 它不会扩展.对于要添加的每个编译器选项,您必须阅读不兼容的选项,并首先手动删除它们.这将不可避免地失败1.

我的问题是双重的:

  1. CMake集成从哪里获取默认设置,是否可以控制?
  2. 如何设置编译器选项?(如果这个主题过于宽泛,我会很乐意帮助您设置警告级别.)


1 顺便说一下,我复制的解决方案没有考虑到/Wall选项,这也是不兼容的/W4.

cmake visual-c++ visual-studio-2017

21
推荐指数
3
解决办法
2万
查看次数

为 CMakeLists.txt 之一禁用 -Werror

我有以下 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

7
推荐指数
1
解决办法
1万
查看次数

CMake 每个文件优化

在其他地方有人问过这样的问题:“如何关闭一个文件的优化?” 答案通常是这样的:

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的文档

编译此源文件时要添加的其他标志。

这是有道理的,它被添加到 COMPILE_FLAGS 列表中,它不会覆盖现有的编译器标志。

那么,在 CMake 中如何覆盖单个文件的优化级别并能够编译项目的其余部分Release?否则,您可以强制编译为CMAKE_BUILD_TYPE=""默认行为,但这在某种程度上违背了 Cmake 的卖点。

cmake

6
推荐指数
1
解决办法
3571
查看次数

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)

c++ linker cmake

5
推荐指数
1
解决办法
1万
查看次数

CMake缓存变量与全局属性:使用变量值的简单语法

要使值从子目录中可用于整个CMake环境,可以使用set(VARIABLE_NAME Value CACHE INTERNAL "")语法设置缓存变量或使用语法设置全局属性set_property(GLOBAL PROPERTY VARIABLE_NAME Value)(另请参阅关于CMake中变量的非常好的答案).

使用后者的优点是,您不会为CMake缓存"污染"它未设计的内容,并且在不使用FORCE参数时您不依赖于被删除的缓存.

但是使用变量值的语法不是用户友好的,因为您必须使用get_property而不是简单地使用${...}表示法来检索值.

是否有更简单的语法来代替get_property(某种语法糖)?

properties global-variables cmake

5
推荐指数
1
解决办法
3776
查看次数

如何配置cmake使用/ MP选项生成Visual Studio 2013+项目文件的方式

我有一个cmake项目,其中包含许多cpp文件(大约400多个),并且使用/ MP(多线程)编译器选项可以在具有多个内核的CPU上显着加快编译速度。

问题是,每次我使用CMake重新生成解决方案文件时,该选项都被禁用,导致编译非常慢。我可以通过在Visual Studio中手动更改每个单个项目(解决方案包含许多不同项目)的选项来解决此问题。但是,每次我通过运行CMake重新生成解决方案文件时(例如,当我git pull别人的更改来添加/删除一些文件时),此更改就会被覆盖。

我如何使其具有持久性,以便CMake始终在VS项目内部启用多线程编译?

cmake visual-studio-2013

4
推荐指数
1
解决办法
1627
查看次数

在2.8.12之前的target_include_directories?

我们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及更早版本?

versioning cmake

4
推荐指数
1
解决办法
2421
查看次数

如何创建继承自 Release 的 CMake 配置类型

此答案描述了如何从头开始创建自定义配置类型。如何制作与 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,所以我想知道是否有用户可能期望的我遗漏的东西?

c c++ cmake

3
推荐指数
1
解决办法
1775
查看次数

多个 CMake 目标的 target_compile_definitions?

有人 告诉我,CFLAGS直接在 CMake 中进行设置是不好的做法,相反,我应该使用该target_compile_definitions()命令。

好的,但是 - 如果我想对多个(独立)目标使用相似/相同的定义怎么办?我不想一遍又一遍地重复自己。

idioms dry cmake compiler-options

3
推荐指数
1
解决办法
3464
查看次数

CMake不使用add_compile_options应用编译选项

我试图使用带有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)

g++ cmake

1
推荐指数
1
解决办法
1856
查看次数