接触C++项目的人都知道,现在存在很多组织源代码进行编译的工具,windows平台下的nmake,visual studio(不同版本的sln project文件)以及Eclipse的CDT。cmake所处的位置,更像是这些已有工具的管理工具,它可以根据cmakelists文件来生成相应的makefile,project文件等等。

使用cmake的好处有很多。编写一次配置文件,就可以在不同的开发平台,不同的编译环境下使用。强大的定制功能,弥补很多工具自身的不足。自动化管理依赖,节省开发人员的时间和编译时间。等等。当然也有他的不足。每一个工具都是有自己的局限性。学习曲线比较陡峭。编译过程变的稍微复杂,需要首先生成中间格式的文件,然后才能编译生成最终的文件。学习资料很少很散。

有好处有坏处,需要的就是权衡。在我看来,cmake提供的功能比较诱人,将代码的配置信息与build环境剥离。这样做为程序员提供了很大的灵活性。

下载安装都很简单,直接到cmake的主页上下载安装包,按提示操作。

 

文件目录结构

在每一层目录下创建一个cmakelists.txt的文件,父目录的cmakelists文件可以指定包含的子目录,子目录的cmakelists则管理该目录下所有的sourcecode。目录可以多层嵌套,组织比较灵活,但是不建议目录层数太深。

 



Dir  Helloworld                                 The project
| File cmakelists.txt The project main cmakelists.txt, which should define the whole project’s properties and include sub dir
| Dir HelloworldTest The app dir, which contains the main function
| | File cmakelists.txt The app cmakelists.txt, which defines all the source files, compiler flags and link flags.
| | File main.cpp The cpp file
| Dir Hellowould The library dir
| | File cmakelists.txt The library cmakelists.txt, which should define all source files and build flags
| | File helloworld.h header file
| | File helloworld.cpp cpp file


 


 

从上边的目录结构可以看出,每一层目录下边都有一个cmakelists.txt。

文件内容:   

Helloworld/cmakelists.txt

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )

project( Helloworld )

set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /machine:x86" ) 

add_subdirectory( Helloworld )               

add_subdirectory( Helloworldtest )

Helloworld/Helloworld/cmakelists.txt

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )

set( HelloWorldSrc helloworld.cpp helloworld.h )

add_library( Helloworld STATIC ${HelloWorldSrc} )

 

Helloworld/HelloworldTest/cmakelists.txt

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )

set( HelloWorldTestSrc main.cpp)

include_directories( "${Helloworld_SOURCE_DIR}/Helloworld" )

add_executable( HelloworldTest ${HelloWorldTestSrc} )

target_link_libraries(HelloworldTest Helloworld )

add_dependencies( HelloworldTest Helloworld )

 

以上是最简单的cmake应用,使用了很基础的cmake命令,这里简单描述一下:

cmake_minimum_required( VERSION 2.8 ) :表示当前cmakelists文件要求cmake版本最低为2.8

project( Helloworld ) :整个项目的名字,在我们的项目中,Helloworld。这个在visual studio中对应solution的名字。

set( NAME VAL1 VAL2 ) :设置变量NAME,值为VAL1;VAL2的列表。CMAKE中列表使用;分隔。如果需要空格分隔的结果,可以用双引号转换。

include_directories():包含一个目录

add_executable(): 增加一个编译单元,目标文件为可执行文件,在windows上则为exe文件。

add_library():添加一个编译单元,目标文件为库。

以上命令的详细解释,可以参考cmake的帮助文档。


 

 

 

Visual Studio属性与对应cmakelists实现方法

注意:此附录仅为beta版本,有些条目是推导出来的。

 


Visual Studio

 

 

Cmake

Project Reference

 

 

add_dependencies()

General/Output Directory

 

 

 

 

 

 

 

 

 

 

 

Debugging/Working Directory

 

 

CMAKE can’t set this value, because the info not stored in project file but some intermedia file generated by visual studio

 

 

 

 

c/c++

General

Additional Include Directories

include_directories()

 

 

Resolve #using References

Don’t know

 

 

Debug Information Format

​CMAKE FAQ​​set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")

set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")

set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")

set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")

Change the default flags for specific config.

 

 

Common language runtime support

set_target_properties( target PROPERTIES COMPILE_FLAGS “/clr”)

set_target_properties( target PROPERTIES COMPILE_FLAGS “/clr:pure”)

set_target_properties( target PROPERTIES COMPILE_FLAGS “/clr:safe”)

set_target_properties( target PROPERTIES COMPILE_FLAGS “/clr:oldSynax”)

 

 

Suppress Startup Banner

set_target_properties( target PROPERTIES COMPILE_FLAGS “/nologo” )

 

 

Warning Level

set_target_properties( target PROPERTIES COMPILE_FLAGS “/W0” )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/W1” )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/W2” )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/W3” )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/W4" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Wall” )

 

 

Treat Warnings As Errors

set_target_properties( target PROPERTIES COMPILE_FLAGS “/WX-" ) #No

set_target_properties( target PROPERTIES COMPILE_FLAGS “/WX" )  #Yes

 

 

Multi-processor Compilation

set_target_properties( target PROPERTIES COMPILE_FLAGS “/MP" )  #Yes

#Don’t set means No

 

 

Use Unicode For Assembler Listing

set_target_properties( target PROPERTIES COMPILE_FLAGS “/FAu" ) #yes

#Don’t set means no

 

Optimization

Optimization

set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")

set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")

set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")

set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")

Change the default flags for specific config.

 

 

Inline Function Expansion

set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")

set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")

set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")

set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")

Change the default flags for specific config.

 

 

Enable Intrinsic Functions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Oi" ) #yes

#Don’t set means no

 

 

Favor Size or Speed

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Os" ) #size

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Ot" ) #speed

#Don’t set means neither

 

 

Omit Frame Pointers

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Oy-" ) #no

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Oy" ) #yes

 

 

Enable Fiber-safe Optimizations

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GT" ) #yes

#not setting means no

 

 

Whole Program Optimization

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GL" ) #yes

#not setting means no

 

Preprocessor

Preprocessor Definitions

set_target_properties( target PROPERTIES COMPILE_DEFINITIONS DEFNAME=DEFVAL )

set_source_files_properties( filename.cpp PROPERTIES COMPILE_DEFINITIONS DEFNAME=DEFVAL )

 

 

Undefine Preprocessor Definitions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/UDEFNAME" )

 

 

Undefine All Preprocessor Definitions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/u" )

 

 

Ignore Standard Include Path

set_target_properties( target PROPERTIES COMPILE_FLAGS “/X" )

 

 

Preprocess to a File

set_target_properties( target PROPERTIES COMPILE_FLAGS “/P" )

 

 

Preprocess Suppress Line Numbers

set_target_properties( target PROPERTIES COMPILE_FLAGS “/EP" )

 

 

Keep Comments

set_target_properties( target PROPERTIES COMPILE_FLAGS “/C" )

 

Code Generation

Enable String Pooling

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GF" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GF-" ) #no

 

 

Enable Minimum Rebuild

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Gm" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Gm-" )#no

 

 

Enable C++ Exceptions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/EHsc" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/EHa" ) #yes, with SEH exceptions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/EHs" ) #yes, with extern C functions

#not setting means no

 

 

Smaller Type Check

set_target_properties( target PROPERTIES COMPILE_FLAGS “/RTCc" ) #yes

#not setting means no

 

 

Basic Runtime Checks

set_target_properties( target PROPERTIES COMPILE_FLAGS “/RTCs" ) #Stack frame check

set_target_properties( target PROPERTIES COMPILE_FLAGS “/RTCu" ) #Uninitialized Variable

set_target_properties( target PROPERTIES COMPILE_FLAGS “/TRC1" ) #Both

#not setting means no

 

 

Runtime Library

​CMAKE FAQ​​set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")

set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")

set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")

set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")

Change the default flags for specific config.

 

 

Struct Member Alignment

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zp1" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zp2" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zp4" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zp8" )set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zp16" )

 

 

Buffer Security Check

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GS" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GS-" ) #no

 

 

Enable Function-Level Linking

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Gy" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Gy-" ) #no

 

 

Enable Enhaunced Instruction Set

set_target_properties( target PROPERTIES COMPILE_FLAGS “/arch:SSE" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/arch:SSE2" )

 

 

Floating Point Model

set_target_properties( target PROPERTIES COMPILE_FLAGS “/fp:precise" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/fp:strict" )

set_target_properties( target PROPERTIES COMPILE_FLAGS “/fp:fast" )

 

 

Enable Floating Point Exceptions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/fp:except" )

 

 

Create Hotpatchable Image

set_target_properties( target PROPERTIES COMPILE_FLAGS “/hotpatch" )

 

Language

Disable Language Extensions

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Za" )

 

 

Treat Wchar_t As Built in Type

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zc:wchar_t" )#yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/Zc:wchar_t-" ) #no

 

 

Force Conformance in For Loop Scope

 

 

 

Enable Run-Time Type Information

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GR" ) #yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/GR-" ) #no

 

 

Open MP Support

set_target_properties( target PROPERTIES COMPILE_FLAGS “/openmp" )#yes

set_target_properties( target PROPERTIES COMPILE_FLAGS “/openmp-" )#no

 

PreCompiled Header

PreCompiled Header

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Yc" ) #create

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Yu" ) #use

#not setting means no

 

 

PreCompiled Header File

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Ycstdafx.h" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Yustdafx.h" )

 

 

Precompiled Header output File

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FpPathAndName.pch" )

 

Output Files

Expand Attributed Source

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Fx" )

 

 

Assembler Output

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FA" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FAc" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FAs" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FAcs" )

#not setting means no list

 

 

ASM List Location

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FaDebug" )

 

 

Object File name

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FoName.obj" )

 

 

Program DataBase File Name

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FdC:/Debug/good.pdb" )

 

 

Generate XML Documentation Files

set_target_properties( target PROPERTIES COMPILE_FLAGS "/doc" )

 

 

XML Documentation Filename

set_target_properties( target PROPERTIES COMPILE_FLAGS "/docDocument.xml" )

 

Browse Information

Enable Browse Information

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FR" )

 

 

Browse Information File

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FRfilename" )

 

Advanced

Calling Convention

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Gd" ) #_cdecl

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Gr" )  #_fastcall

set_target_properties( target PROPERTIES COMPILE_FLAGS "/Gz" ) #_stdcall

 

 

Compile As

set_target_properties( target PROPERTIES LINKER_LANGUAGE "CXX" ) #C++

set_target_properties( target PROPERTIES LINKER_LANGUAGE "C" ) #C

or

set_target_properties( target PROPERTIES COMPILE_FLAGS "/TP" ) #CXX

set_target_properties( target PROPERTIES COMPILE_FLAGS "/TC" ) #C

 

 

Disable Specific Warnings

set_target_properties( target PROPERTIES COMPILE_FLAGS "/wd4710" )

 

 

Forced Include File

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FIinclude.h" )

 

 

Forced #using File

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FUname" )

 

 

Show Includes

set_target_properties( target PROPERTIES COMPILE_FLAGS "/showIncludes" )

 

 

Use full Paths

set_target_properties( target PROPERTIES COMPILE_FLAGS "/FC" )

 

 

Omit Default Library name

set_target_properties( target PROPERTIES COMPILE_FLAGS "/ZI" )

 

 

Internal Compiler Error Reporting

set_target_properties( target PROPERTIES COMPILE_FLAGS "/errorReport:queue" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/errorReport:none" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/errorReport:prompt" )

set_target_properties( target PROPERTIES COMPILE_FLAGS "/errorReport:send" )

 

 

Treat Specific Warnings as Errors

Don't know

Linker

General

Output File

#normal case

set_target_properties( target PROPERTIES OUTPUT_NAME "Helloworld" )

set_target_properties( target PROPERTIES PREFIX "lib" )

set_target_properties( target PROPERTIES SUFFIX "lib" )


#for debug version

set_target_properties( target PROPERTIES DEBUG_OUTPUT_NAME "Helloworld" )

set_target_properties( target PROPERTIES DEBUG_PREFIX "lib" )

set_target_properties( target PROPERTIES DEBUG_SUFFIX "lib" )


#For dlls

set_target_properties( target PROPERTIES OUTPUT_NAME "Helloworld" )

set_target_properties( target PROPERTIES IMPORT_PREFIX "lib" )

set_target_properties( target PROPERTIES IMPORT_SUFFIX "lib" )

set_target_properties( target PROPERTIES PREFIX "bin" )

set_target_properties( target PROPERTIES SUFFIX "dll" )


#output path

 

 

Show Progress

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE" )

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE:Lib" )

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE:ICF" )

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE:REF" )

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE:SAFESEH" )

set_target_properties( target PROPERTIES LINK_FLAGS "/VERBOSE:CLR" )

#not setting means no

 

 

Version

set_target_properties( target PROPERTIES VERSION 0.1.2.3)

 

 

Enable Incremental Linking

set_target_properties( target PROPERTIES LINK_FLAGS "/INCREMENTAL" )

set_target_properties( target PROPERTIES LINK_FLAGS "/INCREMENTAL:NO" )


set( CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL" )

set( CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL:NO" )

 

 

Suppress Startup Banner

set_target_properties( target PROPERTIES LINK_FLAGS "/NOLOGO" )

 

 

Ignore Import Library

Don't know

 

 

Register Output

Don't know

 

 

Per-user Redirection

Don't know

 

 

Additional Library Directories

link_directories( dir1 dir2 )


set_target_properties( target PROPERTIES LINK_FLAGS "/LIBPATH:dir1 /LIBPATH:dir2" )

 

 

Link Library Dependencies

Don't know

 

 

Use Library Dependency Inputs

Don't know

 

 

Link Status

set_target_properties( target PROPERTIES LINK_FLAGS "/LTCG:STATUS" )

set_target_properties( target PROPERTIES LINK_FLAGS "/LTCG:NOSTATUS" )

 

 

Prevent DLL Binding

set_target_properties( target PROPERTIES LINK_FLAGS "/ALLOWBIND:NO" )

set_target_properties( target PROPERTIES LINK_FLAGS "/ALLOWBIND:YES" )

 

 

Treat Linker Warnings As Errors

set_target_properties( target PROPERTIES LINK_FLAGS "/WX" )

 

 

Force File Output

set_target_properties( target PROPERTIES LINK_FLAGS "/FORCE" )

 

 

Create Hot Patchable Image

set_target_properties( target PROPERTIES LINK_FLAGS "/FUNCTIONPADMIN" )

set_target_properties( target PROPERTIES LINK_FLAGS "/FUNCTIONPADMIN:16" ) #Itanium only

set_target_properties( target PROPERTIES LINK_FLAGS "/FUNCTIONPADMIN:6" ) #x64 only

set_target_properties( target PROPERTIES LINK_FLAGS "/FUNCTIONPADMIN:5" ) #x86 only

 

 

Specify Section Attributes

Don't know

 

Input

Additional Dependancies

target_link_libraries( target item1 item2 )

 

 

Ignore All Default Libraries

set_target_properties( target PROPERTIES LINK_FLAGS "/NODEFAULTLIB" )

 

 

 

 

 

 

 

 

 

 

 

 

Put files into folders

 

 

source_group( header FILES includeme.h )

 

 

 

 

 

 

 

 

 

 

 

 


 

结论:CMAKE默认会修改的选项有时候是没有办法再次修改的。CMAKE默认不修改的选项大部分情况都可以自己定义。

 


你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!

没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。