接触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 FAQset(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 FAQset(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 |
|
|
| Object File name | set_target_properties( target PROPERTIES COMPILE_FLAGS "/FoName.obj" ) |
|
| Program DataBase File Name |
|
|
| 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默认不修改的选项大部分情况都可以自己定义。
你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。