CMakeLists 编写.docx
《CMakeLists 编写.docx》由会员分享,可在线阅读,更多相关《CMakeLists 编写.docx(14页珍藏版)》请在冰豆网上搜索。
CMakeLists编写
CMake简介
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。
他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。
CMake使用方法
CMake的所有的语句都写在一个叫:
CMakeLists.txt的文件中。
当CMakeLists.txt文件确定后,可以用ccmake命令对相关的变量值进行配置。
这个命令必须指向CMakeLists.txt所在的目录。
配置完成之后,应用cmake命令生成相应的makefile(在Unixlike系统下)或者project文件(指定用window下的相应编程工具编译时)。
其基本操作流程为:
$>ccmakedirectory
$>cmakedirectory
$>make
其中directory为CMakeList.txt所在目录;
第一条语句用于配置编译选项,如VTK_DIR目录,一般这一步不需要配置,直接执行第二条语句即可,但当出现错误时,这里就需要认为配置了,这一步才真正派上用场;
第二条命令用于根据CMakeLists.txt生成Makefile文件;
第三条命令用于执行Makefile文件,编译程序,生成可执行文件;
CMake的执行就是这么简单,其难点在于如何编写CMakeLists.txt文件,下面结合例子简单介绍CMakeLists.txt的编写,看下面这个CMakeLists.txt
#projectname
PROJECT(test_math)
#headfilepath
INCLUDE_DIRECTORIES(
include
)
#sourcedirectory
AUX_SOURCE_DIRECTORY(srcDIR_SRCS)
#setenvironmentvariable
SET(TEST_MATH
${DIR_SRCS}
)
#setexternlibraries
SET(LIBRARIES
libm.so
)
#addexecutablefile
ADD_EXECUTABLE(../bin/bin${TEST_MATH})
#addlinklibrary
TARGET_LINK_LIBRARIES(../bin/bin${LIBRARIES})
或者用下面这个CMakeLists.txt
#projectname
PROJECT(test_math)
#headfilepath
INCLUDE_DIRECTORIES(include)
#sourcedirectory
AUX_SOURCE_DIRECTORY(srcDIR_SRCS)
#setenvironmentvariable
SET(TEST_MATH${DIR_SRCS})
#addexecutablefile
ADD_EXECUTABLE(../bin/bin${TEST_MATH})
#addlinklibrary
TARGET_LINK_LIBRARIES(../bin/bin m)
这是一个测试数学函数的程序的CMakeLists.txt,"#"后面为注释的内容,CMake的命令全部为大写
第2行指定生成的工程名为test_math
第4行指定头文件目录为include
第8行指定源文件目录为src,并将其赋值给环境变量DIR_SRCS
第10行设定环境变量TEST_MATH的值为环境变量DIR_SRCS的值,此处用于显示如何用环境变量对环境变量进行赋值
第14行将数学函数库赋值给环境变量LIBRARIES,当然,可以不用这个环境变量,而在后面直接使用该库名
第18行用于指定生成文件,将环境变量TEST_MATH目录下的所有文件编译生成../bin目录下的可执行文件bin
第20行指定../bin/bin执行时的链接库为环境变量LIBRARIES的值-libm.so
下面给出源文件
/src/main.c:
#include
#include"../include/a.h"
int main()
{
double b=25.0;
double a=0.0;
a=get_sqrt(b);
printf("ais%lf,bis%lfn",a,b);
return 0;
}
/src/a.c
#include"../include/a.h"
double get_sqrt(double var1)
{
return sqrt(var1);
}
/include/a.h
#ifndefA_FILE_HEADER_INC
#defineA_FILE_HEADER_INC
#include
double get_sqrt(double var1);
#endif
将CMakeLists.txt放在当前目录下,执行CMakeLists.txt
$>cmake.
$>make
即可生成可执行文件,在目录/bin下的bin文件,好了运行看其效果是否和所想一样。
这一章将从软件开发者的角度来描述如何实用CMake。
也就是说,如果你的目标是用CMake来管理你的生成过程,请阅读这一章。
CMake的输入
COMMAND(args)
这里的COMMAND是命令行的名称,args是用空格分割的参数列表。
典型的,对与每一个项目的目录存在一个CMakeLists.txt。
下面我们将从一个简单的Helloworld例子开始介绍,它的源代码树形文件包含这些文件:
Hello.cCMakeLists.txt
CMakeLists.txt将包含下面两行:
PROJECT(Hello)
ADD_EXECUTABLE(HelloHello.c)
为了生成Hello的可执行程序,你只需依照上面CMake运行的过程描述来生成makefiles文件。
PROJECT命令表明了产生的工作空间的名称。
ADD_EXECUTABLE命令添加可执行的目标到生成程序。
这个简单的程序就只需要这些设置。
如歌你的项目需要一些文件才能编译也很容易,只想修改ADD_EXECUTABLE命令行如下:
ADD_EXECUTABLE(HelloHello.cFile2.cFile3.cFile4.c)
ADD_EXECUTABLE只是很多CMake命令中的一种。
比如更复杂的如下:
PROJECT(HELLO)
SET(HELLO_SRCSHell.cFile2.cFile3.c)
IF(WIN32)
SET(HELLO_SRCS${HELLO_SRCS}WinSupport.c)
ELSE(WIN32)
SET(HELLO_SRCS${HELLO_SRCS}UnixSupport.c)
ENDIF(WIN32)
ADD_EXECUTABLE(Hello${HELLO_SRCS})
#lookfortheTcllibrary
FIND_LIBRARY(TCL_LIBRARYNAMEStcltc184tc183tc182tc180
PATHS/usr/lib/usr/local/lib)
IF(TCL_LIBRARY)
TARGET_ADD_LIBRARY(HelloTCL_LIBRARY)
ENDIF(TCL_LIBRARY)
在这个例子中SET命令用于将源文件组成一个列表。
IF命令用于增加WinSupport.c或者UnixSupport.c到列表中。
最后ADD_EXECUTABLE命令用于采用源文件列表HELLO_SRCS中列出的文件生成可执行文件。
FIND_LIBRARY命令用于寻找在一些指定目录下的特定的Tcl库文件。
如果找到了,就将他们添加到Hello可执行程序的链接命令。
#行为注释行。
CMake是会定义一些使用的变量在CMakeList文件中。
比如,WIN32总是会在windows系统中被定义,而UNIX
总是在UNIX系统中被定义。
生成目标:
(BuildTargets)
SET()
SUBDIRS()
ADD_LIBRARY()
这里生成静态链接文件,例如ADD_LIBRARY(Whole${HELLO_SRC}),就会生成一个libWhole.a可供链接
ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()
CMake会循环的查找从当前目录到SUBDIRS列出的任何子目录的文件。
SET命令用于设定一个变量。
ADD_LIBRARY将添加一个库到目标之中。
ADD_EXECUTABLE添加一个可执行程序到目标列表中。
(Note:
编译器执行的顺序是先编译源文件,然后生成库文件,最后生成可执行文件)。
AUX_SOURCE_DIRECTORY表示一个不在当前目录的包含源文件的目录。
这些源代码将插入当前的库(LIBRARY)中。
所有在AUX_SOURCE_DIRECTORY的文件将被编译(如,*.c,*.cxx,*.cpp等等)。
PROJECT(ProjectName)是一个用在MSVC中的特殊变量,用于为编译器生成项目。
他也为CMAKE定义连个有用的变量:
ProjectName_SOURCE_DIR和ProjectName_BINARY_DIR.
编译的标示和选项。
除了上面列出的命令外,CMakeLists.txt还包含如下的命令:
INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()
这些命令定义了用于编译源代码和生成可执行程序的目录和库。
上面列出的目录的一个很重要的特性是它们会被任何子目录继承。
也就是说,CMake依照目录的分层结构来承袭这些命令。
在每次遇到对这些命令的描述的时候都会被展开一次。
比如说,如果在顶层的CMakeLists文件中有定义INCLUDE_DIRECTORIES(/usr/include)和SUBDIRS(./subdir1),并且在./subdir1/CMakeLists.txt有INCLUDE_DIRECTORIES(/tmp/foobar),于是最后网状的结果是
INCLUDE_DIRECTORIES(/usr/include/tmp/foobar)
CMake会定义许多的模块来查找通常会用到的包,比如OpenGL或Java。
这些模块为你节省了很多的时间来编写这些查找包。
这些模块可以像这样加到你的CMakeList文件中,如下:
INCLUDE(${CMAKE_ROOT}/Modules/FindTCL.cmake)
CMAKE_ROOT总是定义在CMake中,用于指向CMake安装的路径。
查看Modules子目录下的一些文件可以给你提供一些很好的idea关于怎样用这些CMake命令。
给项目文件添加一个新的目录
一个通用的方法来扩展一个项目文件是给他添加一个新的文件夹。
这将包含三个步骤:
1.创建一个新的目录在你的源代码的分层目录中
2.将这个新的目录添加到SUBDIRS命令中
3.在这个新创建的目录中用适当的命令建立一个CMakeLists.txt文件
ThissectiondescribeshowtouseCMakefromthesoftwaredeveloper'spointofview.Thatis,ifyouraimistouseCMaketomanageyourbuildprocess,readthissectionfirst.
InputtoCMake
COMMAND(args)
WhereCOMMANDisthenameofthecommand,andargsisawhite-spaceseparatedlistofargumentstothecommand.(Argumentswithembeddedwhite-spaceshouldbequoted.)TypicallytherewillbeaCMakeLists.txtfileforeachdirectoryoftheproject.Let'sstartwithasimpleexample.Considerbuildinghelloworld.Youwouldhaveasourcetreewiththefollowingfiles:
Hello.c CMakeLists.txt
TheCMakeLists.txtfilewouldcontaintwolines:
PROJECT(Hello)
ADD_EXECUTABLE(HelloHello.c)
TobuildtheHelloexecutableyoujustfollowtheprocessdescribedinRunningCMakeabovetogeneratethemakefilesorMicrosoftprojectfiles.ThePROJECTcommandindicateswhatthenameoftheresultingworkspaceshouldbeandtheADD_EXECUTABLEcommandaddsanexecutabletargettothebuildprocess.That'sallthereistoitforthissimpleexample.Ifyourprojectrequiresafewfilesitisalsoquiteeasy,justmodifytheADD_EXECUTABLElineasshownbelow.
ADD_EXECUTABLE(HelloHello.cFile2.cFile3.cFile4.c)
ADD_EXECUTABLEisjustoneofmanycommandsavailableinCMake.Considerthemorecomplicatedexamplebelow.
PROJECT(HELLO)
SET(HELLO_SRCSHello.cFile2.cFile3.c)
IF(WIN32)
SET(HELLO_SRCS${HELLO_SRCS}WinSupport.c)
ELSE(WIN32)
SET(HELLO_SRCS${HELLO_SRCS}UnixSupport.c)
ENDIF(WIN32)
ADD_EXECUTABLE(Hello${HELLO_SRCS})
#lookfortheTcllibrary
FIND_LIBRARY(TCL_LIBRARYNAMEStcltcl84tcl83tcl82tcl80
PATHS /usr/lib/usr/local/lib)
IF(TCL_LIBRARY)
TARGET_ADD_LIBRARY(HelloTCL_LIBRARY)
ENDIF(TCL_LIBRARY)
InthisexampletheSETcommandisusedtogrouptogethersourcefilesintoalist.TheIFcommandisusedtoaddeitherWinSupport.corUnixSupport.ctothislist.AndfinallytheADD_EXECUTABLEcommandisusedtobuildtheexecutablewiththefileslistedinthesourcelistHELLO_SRCS.TheFIND_LIBRARYcommandlooksfortheTcllibraryunderafewdifferentnamesandinafewdifferentpaths,andifitisfoundaddsittothelinklinefortheHelloexecutabletarget.Notetheuseofthe#charactertodenoteacommentline.
CMakealwaysdefinessomevariablesforusewithinCMakeListfiles.Forexample,WIN32isalwaysdefinedonwindowssystemsandUNIXisalwaysdefinedforUNIXsystems.CMakedefinesanumberofcommands.Abriefsummaryofthemostcommonlyusedcommandsfollowshere.Laterinthedocumentanexhaustivelistofallpre-definedcommandsispresented.(Youmayalsoaddyourowncommands,seetheExtensionGuideformoreinformation.)
BuildTargets:
SET()
SUBDIRS()
ADD_LIBRARY()
这里生成静态链接文件,例如ADD_LIBRARY(Whole${HELLO_SRC}),就会生成一个libWhole.a,可供链接。
ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()
CMakeworksrecursively,descendingfromthecurrentdirectoryintoanysubdirectorieslistedintheSUBDIRScommand.ThecommandSETisusedforsettingavariable,inthiscasetoalistofsourcefiles.(Note:
currentlyonlyCandC++codecanbecompiled.)ADD_LIBRARYaddsalibrarytothelistoftargetsthismakefilewillproduce.ADD_EXECUTABLEaddsanexecutabletothelistoftargetsthismakefilewillproduce.(Note:
sourcecodeiscompiledfirst,thenlibrariesarebuilt,andthenexecutablesarecreated.)TheAUX_SOURCE_DIRECTORYisadirectorywhereothersourcecode,notinthisdirectory,whoseobjectcodeistobeinsertedintothecurrentLIBRARY.AllsourcefilesintheAUX_SOURCE_DIRECTORYarecompiled(e.g.*.c,*.cxx,*.cpp,etc.).PROJECT(PojectName)isaspecialvariableusedintheMSVCtocreatetheprojectforthecompiler,italsodefinestwousefulvariablesforCMAKE:
ProjectName_SOURCE_DIRandProjectName_BINARY_DIR.
Buildflagsandoptions.Inadditiontothecommandslistedabove,CMakeLists.txtoftencontainthefollowingcommands:
INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()
Thesecommandsdefinedirectoriesandlibrariesusedtocompilesourcecodeandbuildexecutables.Animportantfeatureofthecommandslistedaboveisthatareinheritedbyanysubdirectories.Thatis,asCMakedescendsthroughadirectoryhierarchy(definedbySUBDIRS())thesecommandsareexpandedeachtimeadefinitionforacommandisencountered.Forexample,ifinthetop-levelCMakeListsfilehasINCLUDE_DIRECTORIES(/usr/include),withSUBDIRS(./subdir1),andthefile./subdir1/CMakeLists.txthasINCLUDE_DIRECTORIES(/tmp/foobar),thenthenetresultis
INCLUDE_DIRECTORIES(/usr/include/tmp/foobar)
CMakecomeswithanumberofmodulesthatlookforcommonlyusedpackagessuchasOpenGLorJava.ThesemodulessaveyoufromhavingtowritealltheCMakecodetofindthesepackagesyourself.ModulescanbeusedbyincludingthemintoyourCMakeListfileasshownbelow.
INCLUDE(${CMAKE_ROOT}/Modules/FindTCL.cmake)
CMAKE_ROOTisalway