g-var.com | G-VAR's Blog

[译]CMake与Visual Studio

Mon Jul 25, 2016

最近在研究一个用CMake而生成的Visual Studio工程,修改项目属性比较艰难,有些时候还需要手动修改.vcxproj文件。遂想研究研究CMakeGoogle时碰到这么一篇CMake and Visual Studio的文章,想通过翻译的过程来加深学习。


转载请注明出处!

译文链接:CMake与Visual Studio

英文原文:CMake and Visual Studio


CMake可以无缝地生成Visual Studio的解决方案。这篇文章会将CMake命令映射到Visual Studio IDE上,为了更容易学习会附上一个例子。此篇文章主要倾向于使用Visual StudioC++开发者。这里的大多数引用都是基于Visual Studio 2010的,但应该也会同样适用于其他版本。大家可以从前言CMake for Visual Studio Developers开始阅读。注:这篇前言就不翻译了。

介绍

先简单的介绍一段关于CMake理念的背景。通常源文件应该被视为可以由开发者显式修改的任何文件。另外,可以从源文件持续生成的任何东西都应被视为构建过程的输出。每次构建总是会生成大量的临时或中间文件,为了避免生成的文件会弄乱实际的源文件,建议在源文件之外进行构建。

除了像.obj这样典型的中间文件,Visual Studio还会生成更多的临时文件,包括.sln.sbr.suo.vcxproj.user.vcxproj.filters。这些文件不需要(也不应该)被上传到源码库中,因为它们有的时候会非常大,并且这些文件还是用户特定的文件。

Visual Studio的开发者可能会将工程文件.vcproj视为”源”文件,因为它涉及到添加、删除文件以及修改文件的依赖等。然而,通过CMake你可以将工程文件也视为中间文件,因为CMake会自动生成它,并建议将其放置在源文件目录之外。

CMake的构建系统中,构建的”规则”或者是”项目的设置”等都会被定义在称之为CMakeLists.txt的文本文件中。

Visual Studio到CMake的映射

Visual Studio项目的一些常见的操作和设置,以及它们与CMake的对应关系简要地罗列在下面的列表里。(注:表的内容就不翻译了)

例子

CMake Tutorial就是一个非常简单的例子。如果你对基本概念还不太清楚,请去该页面进行参考。这里的例子是个改进版本,用以展示常在Windows下使用的某些具体内容。

示例代码可以通过GitHub获得。而对于那些对Github不太熟悉的人,我将同样的代码打包成了7z文件。鼠标右键点击tutorial-7z.jpg,另存到硬盘上,然后将其重命名为Tutorial.7z,并将文件解压就可以获得源码了。

源码结构

CMake-VisualStudio-Example
|---app
|   |---CMakeLists.txt
|   |---main.cxx
|---math
|   |---advanced
|   |   |---AdvancedFunctions.cxx
|   |   |---AdvancedFunctions.h
|   |---simple
|   |   |---SimpleFunctions.cxx
|   |   |---SimpleFunctions.h
|   |----CMakeLists.txt
|   |---MathExports.h
|---CMakeLists.txt
|---TutorialConfig.h.in

执行CMake

如前所述,对于源外构建的建议,需要创建一个目录来存放由CMake生成的必须的Visual Studio项目文件和大量的CMake的特定文件。

D:\tmp\CMake-VisualStudio-Example> mkdir _build

将这个构建目录作当前的工作目录。

D:\tmp\CMake-VisualStudio-Example> cd _build

执行CMake命令,并指定第一次找到的(也就是根目录下)CMakeLists.txt的路径。在这种情况下,使用”..“来指定当前工作目录的上一级目录。-G选项可以指定CMake生成Visual Studio 2010 Win64的项目文件。请注意,也可以指定其他的生成器。

D:\tmp\CMake-VisualStudio-Example\_build> cmake .. -G "Visual Studio 10 Win64"

然后,Visual Studio的工程文件就会被创建在_build目录下。

Visual Studio的解决方案视图

Visual Studio中打开解决方案文件。

image

编译和运行

Visual Studio中编译解决方案。编译会生成二进制文件(app.exe、math.dll),这些文件分别位于_build目录下的相应子目录下。所以现在这种情况下还不能运行可执行文件,因为会找不到math.dll

这也就是安装工程的作用了。单独编译INSTALL.vcproj,因为它并不会作为解决方案的一部分而被编译。这个工程会将二进制文件拷贝到_build\bin目录下。

现在可以在命令行窗口中运行可执行文件。

D:\tmp\CMake-VisualStudio-Example\_build\bin> app.exe 200
The sum of 200 and 200 is 400
The square root of 200 is 14.1421

测试

从构建目录调用CTest就可以运行测试。另外,测试也可以在Visual Studio下通过右键Build RUN_TESTS工程来进行,并且测试的运行报告会被显示在输出窗口中。

D:\tmp\CMake-VisualStudio-Example\_build> ctest
Test project D:/tmp/CMake-VisualStudio-Example/_build
    Start 1: AppTest1
1/3 Test #1: AppTest1    Passed    0.00 sec
    Start 2: AppTest2
2/3 Test #2: AppTest2    Passed    0.00 sec
    Start 3: AppTest3
3/3 Test #3: AppTest3    Passed    0.00 sec

100% tests passed, 0 tests failed out of 3

Total Test time (real) =   0.03 sec 

CMakeLists.txt详解

文件中的每一行注释是关于CMake命令详细解释。

File: CMake-VisualStudio-Example/CMakelist.txt

cmake_minimum_required (VERSION 2.6)

# Maps to Visual Studio solution file (Tutorial.sln)
# The solution will have all targets (exe, lib, dll) 
# as Visual Studio projects (.vcproj)
project (Tutorial)

# Turn on the ability to create folders to organize projects (.vcproj)
# It creates "CMakePredefinedTargets" folder by default and adds CMake
# defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Set compiler flags and options. 
# Here it is setting the Visual Studio warning level to 4
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")

# Command to output information to the console
# Useful for displaying errors, warnings, and debugging
message ("cxx Flags: " ${CMAKE_CXX_FLAGS})

# Sub-directories where more CMakeLists.txt exist
add_subdirectory(app)
add_subdirectory (math)

# Turn on CMake testing capabilities
enable_testing()

# Add test cases
add_test(AppTest1 ${PROJECT_BINARY_DIR}/bin/app.exe 100)
add_test(AppTest2 ${PROJECT_BINARY_DIR}/bin/app.exe 200)
add_test(AppTest3 ${PROJECT_BINARY_DIR}/bin/app.exe 300)

File: CMake-VisualStudio-Example/math/CMakeLists.txt

# Collect sources into the variable MATH_SOURCES without
# having to explicitly list each header and source file.
#
# CMake documentation states "We do not recommend using GLOB to collect a
# list of source files from your source tree. If no CMakeLists.txt file
# changes when a source is added or removed then the generated build system
# cannot know when to ask CMake to regenerate".
file (GLOB MATH_SOURCES
  "*.h")

# Collect sources into the variable SIMPLE_FUNCTION_SOURCES
file (GLOB SIMPLE_FUNCTION_SOURCES
  "simple/*.h",
  "simple/*.cxx")

# The recommended way to collect sources in variable 
# ADVANCED_FUNCTION_SOURCES by explicitly specifying the source files
set  (ADVANCED_FUNCTION_SOURCES
  "advanced/AdvancedFunctions.h"
  "advanced/AdvancedFunctions.cxx")

# Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj
source_group("" FILES ${MATH_SOURCES})
source_group("simple" FILES ${SIMPLE_FUNCTION_SOURCES})
source_group("advanced" FILES ${ADVANCED_FUNCTION_SOURCES})

# Properties->C/C++->General->Additional Include Directories
include_directories (.)

# Set Properties->General->Configuration Type to Dynamic Library(.dll)
# Creates math.dll with the listed sources collected in the variables
# Also adds sources to the Solution Explorer
add_library(math SHARED ${MATH_SOURCES} 
                    ${SIMPLE_FUNCTION_SOURCES} 
                    ${ADVANCED_FUNCTION_SOURCES})

# Creates folder "libraries" and adds target project (math.vcproj)
set_property(TARGET math PROPERTY FOLDER "libraries")

# Adds logic to INSTALL.vcproj to copy math.dll to destination directory
install (TARGETS math
     RUNTIME DESTINATION ${PROJECT_BINARY_DIR}/bin)

File: CMake-VisualStudio-Example/app/CMakeLists.txt

# Properties->C/C++->General->Additional Include Directories
include_directories ("${PROJECT_SOURCE_DIR}/Math")

# Set Properties->General->Configuration Type to Application(.exe)
# Creates app.exe with the listed sources (main.cxx)
# Adds sources to the Solution Explorer
add_executable (app main.cxx)

# Properties->Linker->Input->Additional Dependencies
target_link_libraries (app math)

# Creates a folder "executables" and adds target 
# project (app.vcproj) under it
set_property(TARGET app PROPERTY FOLDER "executables")

# Adds logic to INSTALL.vcproj to copy app.exe to destination directory
install (TARGETS app
     RUNTIME DESTINATION ${PROJECT_BINARY_DIR}/bin)

CMake的预定义工程

为了给Visual Studio环境中添加一些CMake的功能,CMake创建了一些很大程度上被忽略了的工程文件。不管怎么样,下面给出了这些工程的简单描述。

image

Debug and Release Configurations

Visual Studio支持在单个工程文件中具有多个配置,并且会给每个配置创建一个目录。CMake默认会生成四种配置:DebugReleaseMinSizeRelRelWithDebInfo

可以访问下面的链接来查看如何修改这些默认值。

CMake Wiki: How can I specify my own configurations (for generators that allow it) ?

总结

CMake是一个比Visual Studio的工程和解决方案更好的构建系统。它结构紧凑,并且即使是针对仅适用于Windows的项目,它也是更易于维护的。

希望这篇文章会对大家有用。如果您有任何疑惑或者其他信息可以随意评论。

[ 转载必须在正文中标注并保留原文链接等信息。]



  « Previous: Next: »