http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/http://blog.csdn.net/dbzhang800/article/details/6314073
Http://www.cnblogs.com/coderfenghc/archive/2013/01/20/2846621.html
Http://blog.sina.com.cn/s/blog_4aa4593d0100q3bt.html
http://hahack.com/codes/cmake/
Http://blog.chinaunix.net/uid-24512513-id-3196376.html
Http://www.cppblog.com/tx7do/archive/2010/08/19/124000.html
Http://name5566.com/1795.html
Http://jiyeqian.is-programmer.com/2011/7/4/cmake_tutorial.27813.html
CMake Quick Start Tutorial-combat
0. Preface
One months ago, due to the needs of the project, a hasty study of the use of CMake, now there is time to get out and tidy up a bit. This article assumes that you have learned how to use CMake, and if you do not use CMake, please refer to the relevant information before continuing to look down.
This article describes the methods and steps for generating an executable program, which differs from the method of generating a dynamic library and a static library, and then describes how to write cmake in the dynamic library and static library projects.
This article, referring to the CMake practice, is designed to guide users to quickly use the CMake, and if more details are needed, please read through the article CMake practice. Download path: http://sewm.pku.edu.cn/src/paradise/reference/CMake%20Practice.pdf
1. Project directory Structure
The name of our project is Crnode, assuming that all the files of our project are stored again ~/workspace/crnode, and then without special instructions, we refer to the directory as the relative path.
Our directory structure is as follows:
~/workspace/crnode├─SRC │├─rpc││├─crmastercaller.h││├─crmastercaller.cc││├─crnode.h││├─crnode.cc││ ├─schd_constants.h││├─schd_constants.cc││├─crmaster.h││├─crmaster.cc││├─crnode_server.skele Ton.h││├─crnode_server.skeleton.cc││├─schd_types.h││└─schd_types.cc│├─task││├─taskexecuto R.h││├─taskexecutor.cc││├─taskmonitor.h││└─taskmonitor.cc│├─util││├─const.h││├─con st.cc││├─globals.h││├─globals.cc││├─properties.h││├─properties.cc││├─utils.h││└─ Utils.cc│├─main.cc│└─cmakelists.txt├─doc│└─crnode.txt├─copyright├─readme├─crnode.sh└─cmakeli Sts.txt
Where SRC holds the source code file and a CMakeLists.txt file, the Cmakelists file is written, we'll describe it later; The Doc directory contains the Help documentation for the project, which is installed together with the copyright and Readme in the/usr/share /doc/crnode the contents of the document, the copyright information stored in the project, the Readme store some descriptive text, crnode.sh storage crnode the start command; CMakeLists.txt file is described later.
In addition, the project also relies on two external libraries: The thrift Library developed by Facebook, whose header files are stored in the/usr/include/thrift directory, and the Log4cpp library whose header files are stored and/usr/include.
2. CMakeLists.txt file
This project uses two CMakeLists.txt files, respectively, the root directory of the project (that is, the ~/workspace/crnode directory, the same as the same) and
1234567891011121314 |
Cmake_minimum_required (VERSION 2.6) Project (Crnode) add_subdirectory (src bin) #SET (Cmake_install_ PREFIX ${project_binary_dir}) SET (cmake_install_prefix/usr/local) Install (PROGRAMS crnode.sh DESTINATION bin) Install (FILES COPYRIGHT README DESTINATION share/doc/crnode) INSTALL (DIRECTORY doc/destination share/doc/crnode) |
2.2 Src/cmakelists.txt Content
123456789101112131415161718192021222324 |
Include_directories (/usr/include/thrift) SET (src_list main.cc rpc/crmastercaller.cpp rpc/CRNode_ Server.skeleton.cpp rpc/schd_constants.cpp rpc/crmaster.cpp rpc/crnode.cpp rpc/schd_types.cpp task/taskexecutor.cpp task/taskmoniter.cpp util/const.cpp util/globals.cc util/utils.cc util/properties.cpp ) Add_executable (Crnode ${src_list}) target_link_libraries (Crnode log4cpp Thrift) INSTALL (TARGETS crnode RUNTIME DESTINATION bin) |
3. CMake syntax
A. Variables are evaluated using the ${} method, but the variable names are used directly in the IF control statement;
B. Instructions (parameter 1, parameter 2 ...), the parameters are enclosed in parentheses, and the parameters are separated by a space or semicolon;
C. Directives are case-insensitive, and arguments and variables are case-sensitive. However, it is recommended that you use all uppercase instructions.
4. CMakeLists.txt Anatomy
4.1 cmake_minimum_required Command
1 |
Cmake_minimum_required (VERSION 2.6) |
Specifies the minimum version of the CMake program. This line of command is optional, we can not write this sentence, but in some cases, if you use some of the high version CMake specific commands in the CMakeLists.txt file, you need to add such a line to remind the user to upgrade to the version before the execution of CMake.
4.2 Project Command
The
Specifies the name of the project. The executable file generated by the final compilation of the project is not necessarily the name of the project, but is determined by another command, which we will introduce later.
But this project name is still necessary, there are two predefined variables in CMake:< projectname >_binary_dir and < ProjectName >_source_dir, in our project, The two variables were: Crnode_binary_dir and Crnode_source_dir. The internal compilation situation is the same, we will talk about external compilation, the content of the two refers to different. To understand the definition of these two variables, we first need to understand what is "external build (Out-of-source build), we'll cover "external build" in the next section. The
CMake also pre-defined project_binary_dir and Project_source_dir variables. In our project, Project_binary_dir is equivalent to crnode_binary_dir,project_source_dir equivalent to Crnode_source_dir. In practical applications, I strongly recommend using Project_binary_dir and Project_source_dir variables, so that even if The project name changes and does not affect the CMakeLists.txt file.
4.3 External builds
Suppose we have completed the writing of two CMakeLists.txt files at this time, we can execute the cmake command to generate the makefile file. At this point we have two ways to perform cmake, compile, and install:
Or
1234 |
mkdir BUILDCD Buildcmake. Make |
The biggest difference between the two methods is that the working paths for CMake and make are different. In the first method, all intermediate and executable files generated by CMake are stored in the project directory, and in the second method, both intermediate and executable files are stored in the build directory. The advantage of the second approach is obvious, and it keeps the code catalog tidy. Also, because the second method is generated, compiled, and installed in a different directory than the project directory, the second method is called "External build."
Back to the previous question, in the case of an external build, Project_source_dir points to the same directory as the internal build , still ~/workspace/crnode, and Project_binary_dir is different. Point to the ~/workspace/crnode/build directory.
Of course, CMake strongly recommends the use of externally constructed methods.
4.4 add_subdirectory Command
5 |
Add_subdirectory (src bin) |
Add_subdirectory (Source_dir [Binary_dir] [exclude_from_all]) This instruction is used to add a subdirectory of the source file to the current project, and to specify the location of the intermediate binary and destination binary deposits. The meaning of the Exclude_from_all parameter is to exclude this directory from the compilation process. For example, the example of the project may require the construction of the project to be completed, and then into the example directory to be built separately.
In our project, we add the src directory to the project, and the intermediate and target files corresponding to the SRC directory are stored in the bin directory, and in the example of the previous section "externally constructed", the intermediate and target files will be stored in the build/ The Srcobj directory.
4.5 SET Command
8 |
SET (cmake_install_prefix/usr/local) |
At this stage, you just need to understand that the set command can be used to explicitly define variables. In the example above, we explicitly define the value of Cmake_install_prefix as/usr/local, so when executing the make INSTALL command in an external build , make copies the resulting executable file to/ The Usr/local/bin directory.
Of course, the installation path of the executable file Cmake_install_prefix can also be specified when executing the cmake command, cmake parameters are as follows:
Cmake-dcmake_install_prefix=/usr.
If this value is not specified in the CMake parameter and the CMakeLists.txt file, the value is the default/usr/local.
4.6 include_directories Command
1 |
Include_directories (/usr/include/thrift) |
Include_directories is similar to the compile parameter "-i" in GCC, which specifies the path of the compiler Search header file during compilation. This path needs to be specified when the header file required by the project is not in the system default search path. In our project, the header files required for log4cpp are stored under/usr/include and do not need to be specified, but the thrift header file is not stored in the system path and needs to be specified to search its path.
4.7 Add_executable and Add_library
3456789101112131415161718 |
SET (src_list main.cc rpc/crmastercaller.cpp rpc/crnode_server.skeleton.cpp rpc/schd_constants.cpp rpc/crmaster.cpp rpc/crnode.cpp rpc/schd_types.cpp task/taskexecutor.cpp task/ TaskMoniter.cpp util/const.cpp util/globals.cc util/utils.cc util/properties.cpp ) ADD _executable (Crnode ${src_list}) |
Add_executable defines the project to generate an executable file with the file name Crnode, which is a list of source files defined in Src_list. It is important to note that there is no relationship between the Crnode and the previous project name and can be arbitrarily defined.
4.8 Executable_output_path and Library_output_path
We can redefine the Executable_output_path and Library_output_path variables by the SET directives to specify the location of the final target binary (that is, the resulting crnode executable or the final shared library. Without the intermediate files generated by the compilation).
The command is as follows:
Set (Executable_output_path ${project_binary_dir}/bin) set (Library_output_path ${project_binary_dir}/lib)
It is important to note where add_executable or add_library, if you need to change the target storage path, where to add the above definition.
4.9 target_link_libraries Command
20 |
Target_link_libraries (Crnode log4cpp Thrift) |
This sentence specifies the external library that needs to be linked when linking to the target file, which is similar to the GCC compilation parameter "-L", which solves the dependency problem of the external library.
4.10 Install Command
You need to be aware of the value of the Cmake_install_prefix parameter when executing the INSTALL command. This parameter has already been introduced in 3.5. Its command form is as follows:
Targets ... [[archive| library| Runtime][destination < dir >][permissions PERMISSIONS ...] [Configurations[debug| Release| ...] [COMPONENT < COMPONENT;] [OPTIONAL]] [...])
The TARGETS in the parameter is followed by the target file we defined by add_executable or add_library, possibly executable binary, dynamic library, Static library.
DESTINATION defines the path to the installation, and if the path starts with a/, then the absolute path, then Cmake_install_prefix is actually invalid. If you want to use Cmake_install_prefix to define the installation path, write a relative path, i.e. do not start with/, then the installed path is ${cmake_install_prefix}/< destination defined path >
You don't need to be concerned with the path that TARGETS specifically generates, just write the TARGETS name on it.
Executable program installation of non-target files (such as scripts):
INSTALL (PROGRAMS files ... DESTINATION < dir >[permissions PERMISSIONS ...] [Configurations [Debug| Release| ...] [COMPONENT < COMPONENT;] [RENAME < name;] [OPTIONAL])
As with the FILES instructions above, the only difference is the installation of permissions for Owner_execute, Group_execute, and World_execute, which is the 755 permissions directory.
The command to install a directory is as follows:
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 ...] [...])
The directory behind directories is connected to the relative path of the Source directory, but it is important to note that there is a big difference between ABC and abc/. If the directory name does not end with/, then the directory will be installed as ABC under the target path, and if the directory name ends with a/end, the directory will be installed to the target path, but the directory itself is not included. Let's look at an example:
12345 |
INSTALL (DIRECTORY icons scripts/destination share/myprojpattern "CVS" Excludepattern "scripts/*" PERMISSIONS owner_ EXECUTE owner_write Owner_readgroup_execute Group_read) |
The result of this instruction is:
Install the icons directory to the < prefix >/share/myproj, install the contents of scripts/to < prefix >/share/myproj, without directories named CVS, for scripts/* files Specify a permission of Owner_execute owner_write owner_read group_execute group_read.
Because Crnode.txt is going to be installed to/< prefix >/share/doc/crnode, we cannot install the entire Doc directory directly, by installing the contents of the Doc directory, i.e. using "doc/" in the project file:
1 |
INSTALL (DIRECTORY doc/destination share/doc/crnode) |
5. Compiling the installation
The compiled installation results are as follows:
[Email protected] build]# CMake. --Configuring done--generating done--Build files has been written to:/Home/fify/workspace/crnode/build[[email protected] build]# makescanning dependencies ofTargetcrnode[7%] Building CXX Objectsrcobj/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 Objectsrcobj/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.olinking CXX executable Crnode[[email protected] build]# make install[100%] Built target crnodeinstall The project...--install configuration: ""--Installin G:/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
Done! For more information, please refer to "CMake practice", again to "CMake practice" of the author Express thanks!
CMake Quick Start Tutorial-combat