0. 前言 ~/workspace/CRNode ├─ src │ ├─ rpc │ │ ├─ CRMasterCaller.h │ │ ├─ CRMasterCaller.cc │ │ ├─ CRNode.h │ │ ├─ CRNode.cc │ │ ├─ Schd_constants.h │ │ ├─ Schd_constants.cc │ │ ├─ CRMaster.h │ │ ├─ CRMaster.cc │ │ ├─ CRNode_server.skeleton.h │ │ ├─ CRNode_server.skeleton.cc │ │ ├─ Schd_types.h │ │ └─ Schd_types.cc │ ├─ task │ │ ├─ TaskExecutor.h │ │ ├─ TaskExecutor.cc │ │ ├─ TaskMonitor.h │ │ └─ TaskMonitor.cc │ ├─ util │ │ ├─ Const.h │ │ ├─ Const.cc │ │ ├─ Globals.h │ │ ├─ Globals.cc │ │ ├─ Properties.h │ │ ├─ Properties.cc │ │ ├─ utils.h │ │ └─ utils.cc │ ├─ main.cc │ └─ CMakeLists.txt ├─ doc │ └─ crnode.txt ├─ COPYRIGHT ├─ README ├─ crnode.sh └─ CMakeLists.txt 其中,src存放源代码文件和一个CMakeLists.txt文件,CMakeLists文件的编写我们稍候介绍;doc目录中存放项目 的帮助文档,该文档以及COPYRIGHT和README一起安装到/usr/share/doc/crnode目录中;COPYRIGHT文件存放项目 的版权信息,README存放一些说明性文字;crnode.sh存放CRNode的启动命令;CMakeLists.txt文件稍候介绍。
2.2 src/CMakeLists.txt内容
3. CMake语法 4. CMakeLists.txt剖析
规定cmake程序的最低版本。这行命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.txt文件中使用了一些高版本cmake特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行cmake。 4.2 project命令
指定项目的名称。项目最终编译生成的可执行文件并不一定是这个项目名称,而是由另一条命令确定的,稍候我们再介绍。 4.3 外部构建
或者
两种方法最大的不同在于执行cmake和make的工作路径不同。第一种方法中,cmake生成的所有中间文件和可执行文件都会存放在项目 目录中;而第二种方法中,中间文件和可执行文件都将存放再build目录中。第二种方法的优点显而易见,它最大限度的保持了代码目录的整洁。同时由于第二 种方法的生成、编译和安装是发生在不同于项目目录的其他目录中,所以第二种方法就叫做“外部构建”。 4.4 ADD_SUBDIRECTORY命令
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。 EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除。比如,工程的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建。 4.5 SET命令
现阶段,只需要了解SET命令可以用来显式的定义变量即可。在以上的例子中,我们显式的将CMAKE_INSTALL_PREFIX的值定 义为/usr/local,如此在外部构建情况下执行make install命令时,make会将生成的可执行文件拷贝到/usr/local/bin目录下。 cmake -DCMAKE_INSTALL_PREFIX=/usr .. 如果cmake参数和CMakeLists.txt文件中都不指定该值的话,则该值为默认的/usr/local。 4.6 INCLUDE_DIRECTORIES命令
INCLUDE_DIRECTORIES类似gcc中的编译参数“-I”,指定编译过程中编译器搜索头文件的路径。当项目需要的头文件不在 系统默认的搜索路径时,需要指定该路径。在我们的项目中,log4cpp所需的头文件都存放在/usr/include下,不需要指定;但thrift的 头文件没有存放在系统路径下,需要指定搜索其路径。 4.7 ADD_EXECUTABLE和ADD_LIBRARY
ADD_EXECUTABLE定义了这个工程会生成一个文件名为 CRNode 的可执行文件,相关的源文件是 SRC_LIST 中定义的源文件列表。需要注意的是,这里的CRNode和之前的项目名称没有任何关系,可以任意定义。 4.8 EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) 需要注意的是,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义。 4.9 TARGET_LINK_LIBRARIES命令
这句话指定在链接目标文件的时候需要链接的外部库,其效果类似gcc的编译参数“-l”,可以解决外部库的依赖问题。 4.10 INSTALL命令 INSTALL(TARGETS targets... [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION < dir >] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT < component >] [OPTIONAL] ] [...]) 参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的目标文件,可能是可执行二进制、动态库、静态库。 INSTALL(PROGRAMS files... DESTINATION < dir > [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT < component >] [RENAME < name >] [OPTIONAL]) 跟上面的 FILES 指令使用方法一样,唯一的不同是安装后权限为OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限目录的安装。 INSTALL(DIRECTORY dirs... DESTINATION < dir > [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [USE_SOURCE_PERMISSIONS] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT < component >] [[PATTERN < pattern > | REGEX < regex >] [EXCLUDE] [PERMISSIONS permissions...]] [...]) DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意:abc 和 abc/有很大的区别。如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。我们来看一个例子:
这条指令的执行结果是:
5. 编译安装 [root@sim91 build]# cmake .. -- Configuring done -- Generating done -- Build files have been written to: /home/fify/workspace/CRNode/build [root@sim91 build]# make Scanning dependencies of target crnode [ 7%] Building CXX object srcobj/CMakeFiles/crnode.dir/main.cc.o [ 15%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMasterCaller.cpp.o [ 23%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode_server.skeleton.cpp.o [ 30%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_constants.cpp.o [ 38%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMaster.cpp.o [ 46%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode.cpp.o [ 53%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_types.cpp.o [ 61%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskExecutor.cpp.o [ 69%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskMoniter.cpp.o [ 76%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Const.cpp.o [ 84%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Globals.cc.o [ 92%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/utils.cc.o [100%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Properties.cpp.o Linking CXX executable crnode [root@sim91 build]# make install [100%] Built target crnode Install the project... -- Install configuration: "" -- Installing: /usr/local/bin/crnode.sh -- Installing: /usr/local/share/doc/crnode/COPYRIGHT -- Installing: /usr/local/share/doc/crnode/README -- Installing: /usr/local/share/doc/crnode -- Installing: /usr/local/share/doc/crnode/crnode.txt -- Installing: /usr/local/bin/crnode 大功告成!更多内容请参考《CMake Practice》,再次对《CMake Practice》的作者表示感谢! |
|