这似乎是一个微不足道的问题,因为CMake是一种脚本语言,一般的答案是:严格顺序.但是我遇到了几个案例,其中重要的是CMake在何时或以何种顺序解析某些文件.所以我想知道:
到目前为止我遇到的案例,上述信息很重要:
CMakeLists.txt文件外部的作用域调用变量监视:在"配置"步骤完成之前,在CMake中执行命令或宏作为最后一步也许你知道更多.
为了找到答案,我尝试了以下内容:我已经设置了一个简单的主CMakeLists.txt,如下所示,并运行cmake --trace …以分析解析顺序.
cmake_minimum_required(VERSION 2.8)
include(BeforeProjectCmd.cmake)
project(ParserTest CXX)
add_subdirectory(LibTarget1)
add_subdirectory(LibTarget2)
add_executable(ExeTarget Test.cpp)
variable_watch(CMAKE_BACKWARDS_COMPATIBILITY)
Run Code Online (Sandbox Code Playgroud)
然后,当我运行时,cmake --debug-output --trace -G"Visual Studio 12 2013" -DCMAKE_TOOLCHAIN_FILE:FILE_PATH=Toolchain.txt我得到了一个很长的痕迹,我试图总结:
# Begin try to read
CMakeCache.txt
${CMAKE_BINARY_DIR}/CMakeCache.txt
PreLoad.cmake
${CMAKE_BINARY_DIR}/PreLoad.cmake
# End try to read
? CMakeLists.txt(1): cmake_minimum_required(VERSION 2.8 )
? CMakeLists.txt(3): include(BeforeProjectCmd.cmake )
?
?? BeforeProjectCmd.cmake
?
? CMakeLists.txt(5): project(ParserTest CXX )
?? share/cmake-3.2/Modules/CMakeDetermineSystem.cmake
??
??? Toolchain.txt
?
?? ${CMAKE_PLATFORM_INFO_DIR}/CMakeSystem.cmake
??
??? …Run Code Online (Sandbox Code Playgroud) 我最近遇到了几个关于改善CMake启用C++项目周转时间的具体方面的问题(比如"我应该在什么级别分配我的构建过程?"或"cmake rebuild_cache 只是一个子目录?"),我是想知道是否有更一般的指导利用CMake提供的特定可能性.如果可能没有跨平台编译时优化,我主要对Visual Studio或基于GNU toochain的方法感兴趣.
我已经意识到并投资了一般推荐的领域来加速C++构建:
更改/优化/微调工具链
优化您的代码库/软件架构(例如,通过减少依赖关系并使用明确定义的子项目 - 单元测试)
投资更好的硬件(SSD,CPU,内存)
喜欢在这里,这里或这里推荐.所以我在这个问题上的重点是第一点.
另外我知道在CMake的Wiki中可以找到的建议:
前者只处理基础(并行make),后者主要处理如何加速解析CMake文件.
为了使这更具体一点,如果我从这里使用MSYS/GNU的100个库获取我的CMake示例,我得到了以下time测量结果:
$ cmake --version
cmake version 3.5.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ time -p cmake -G "MSYS Makefiles" ..
-- The CXX compiler identification is GNU 4.8.1
...
-- Configuring done
-- Generating done
-- Build files have been written to: [...]
real 27.03
user …Run Code Online (Sandbox Code Playgroud) 我有几个项目(所有建筑都使用来自相同源树结构的CMake)都使用他们自己的混合数十个支持库.
所以我想到了如何在CMake中正确设置这个问题.到目前为止,我只发现CMake如何正确地创建目标之间的依赖关系,但我仍然在设置所有具有全局依赖关系(项目级别确实知道所有)或本地依赖关系(每个子级别目标仅处理其自己的依赖).
这里是我的目录结构的简化例子,我现在想出了使用CMake和本地依赖性(例子中只有一个可执行的项目,App1但也有更多的实际,App2,App3等):
Lib
+-- LibA
+-- Inc
+-- a.h
+-- Src
+-- a.cc
+-- CMakeLists.txt
+-- LibB
+-- Inc
+-- b.h
+-- Src
+-- b.cc
+-- CMakeLists.txt
+-- LibC
+-- Inc
+-- c.h
+-- Src
+-- c.cc
+-- CMakeLists.txt
App1
+-- Src
+-- main.cc
+-- CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)
LIB /力霸/的CMakeLists.txt
include_directories(Inc ../LibC/Inc)
add_subdirectory(../LibC LibC)
add_library(LibA Src/a.cc Inc/a.h)
target_link_libraries(LibA LibC)
Run Code Online (Sandbox Code Playgroud)
LIB/LibB /的CMakeLists.txt
include_directories(Inc)
add_library(LibB Src/b.cc Inc/b.h)
Run Code Online (Sandbox Code Playgroud)
LIB /的LibC /的CMakeLists.txt
include_directories(Inc ../LibB/Inc)
add_subdirectory(../LibB LibB)
add_library(LibC …Run Code Online (Sandbox Code Playgroud) 在将OpenCV之类的库与C / C ++一起使用时,使用诸如OpenCV_LIBS之类的变量将编译器/链接器指向相关目录。
使用cmake的示例:
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_link_libraries( project_name ${OpenCV_LIBS} )
Run Code Online (Sandbox Code Playgroud)
如何检查此类变量指向的位置?我尝试在终端输入set或输入printenv,但它仅显示一些系统变量。另外,如何设置/更改此类变量?
我已经围绕标准 CMake 命令编写了一些方便的包装器,并希望对该 CMake 脚本代码进行单元测试以确保其功能。
我已经取得了一些进展,但有两件事我希望得到帮助:
首先,我研究了 /Tests 下,特别是 Tests/CMakeTests 下的 CMake 源代码(我使用的是 CMake 版本 2.8.10)。有大量的品种可供发现,而且看起来其中很多都专门针对单个测试用例。
因此,我还研究了一些可用的 CMake 脚本库(例如CMake++)来查看它们的解决方案,但是当它们进行单元测试时,它们在很大程度上取决于它们自己的库函数。
我想基于动态方式的目标文件中的所有符号生成模块定义文件(想想GTKMM的gendef).
为此,我想add_custom_command为PRE_LINK目标迈出一步.但是,看起来没有简单的方法可以使用CMake获取所有目标文件的路径,这些文件适用于普通的makefile以及Visual Studio等多配置生成器.
现在,我有以下内容
add_custom_command(TARGET tgt PRE_LINK
COMMAND gendef ${CMAKE_CURRENT_BINARY_DIR}/tgt.def $<TARGET_FILE_NAME:tgt> ${CMAKE_CURRENT_BINARY_DIR}/$<$<BOOL:${CMAKE_BUILD_TYPE}>:${CMAKE_FILES_DIRECTORY}>/tgt.dir/${CMAKE_CFG_INTDIR}/*.obj
)
Run Code Online (Sandbox Code Playgroud)
然而,由于我不得不在我看来使用生成器表达,这是非常笨拙和笨重的.有没有更好的方法来实现这种效果,即为每个构建配置调用某个外部程序?
它是一个CMake错误(功能?),对于普通的makefile,所有目标文件都转到CMakeFiles/tgt.dir文件夹,而对于多配置生成器,所有文件都转到CMakeFiles 的兄弟,即tgt.dir/$<CONFIG>?我是否错过了一些简单的变量,可以直接指向正确的位置?
我已在 Visual Studio 2015 中为旧版 C++ 项目激活自动代码格式化。
问题在于,特定宏调用之后的代码行(由于位于宏内部而不以分号结束)始终是缩进的。我正在 Visual Studio 2015 中寻找一个设置来防止这种情况,而无需安装另一个扩展,无需更改宏定义本身或要求每个人在调用中添加一个额外的分号(这将修复它)。
以下是代码和产生的问题的最小示例:
#include <iostream>
#ifdef _DEBUG
# define MY_TRACE(X) do { std::cout << X << std::endl; } while (0);
#else
# define MY_TRACE(X) {}
#endif
int main()
{
MY_TRACE( "Hello World!" )
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我有以下设置,它会自动缩进,例如 on<Enter>或 with }:
以及以下缩进设置:
我已经尝试了那里和其他地方的所有可能和不可能的设置组合(包括例如“制表符/缩进/智能”的转动)。每次 Visual Studio C++ 编辑器都会继续缩进宏后面的行。
我在 SO 或互联网上也找不到任何东西。我得到的最接近的,但没有答案或不同编辑器/语言的位置:
cmake ×6
c++ ×3
compilation ×1
ctest ×1
editor ×1
gnu-make ×1
include-path ×1
library-path ×1
macros ×1
mocking ×1
nmake ×1
opencv ×1
performance ×1
unit-testing ×1
windows ×1