[Zz] Using cmake to build applications in Linux

Source: Internet
Author: User
Tags windows visual

Address: http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/index.html

 

 

This article describes how to use cmake, a cross-platform automated build system, on Linux. Cmake is a tool easier to use than automake, which can free programmers from complicated compilation and connection processes. This article describes how to use cmake to process multi-source file directories, how to find and use other development kits, and how to Generate debug and release programs.

Cmake Introduction

Cmake is a cross-platform automated construction system. It uses a file named cmakelists.txt to describe the building process and generate standard building files, for example, makefile of Unix or projects/workspaces of Windows visual c ++. The file cmakelists.txt needs to be manually written. You can also write a script to generate it semi-automatically. Cmake provides more concise syntax than AutoConfig. The process for generating and compiling makefile using cmake on Linux is as follows:

  1. Write CmakeLists.txt
  2. Execute Command cmake PATH Or ccmake PATH Generate Makefile ( PATH Yes CMakeLists.txt Directory )
  3. Use make Command to compile.

First Project

Assume that only one of our projects is available.Source files main.cpp

Listing 1 source file main. cpp

1 #include<iostream>2 3 int main()4 {5     std::cout<<"Hello word!"<<std::endl;6     return 0;7 }

To build this project, we need to write the file cmakelists.txt and put it in the same directory as main. cpp:

Listing 2 cmakelists.txt

1 PROJECT(main)2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)3 AUX_SOURCE_DIRECTORY(. DIR_SRCS)4 ADD_EXECUTABLE(main ${DIR_SRCS})

The syntax of cmakelists.txt is simple and consists of commands, comments, and spaces. commands are case-insensitive and the content after the symbol "#" is considered as comments. The command consists of the command name, Parentheses, and parameters. The parameters are separated by spaces. For example, for the cmakelists.txt file in Listing 2, the first line is a command named project and the parameter is main. This command indicates that the project name is main. The command line 2 limits the cmake version. The third line uses the command aux_source_directory to assign the source file name in the current directory to the variable dir_srcs. The description of the command aux_source_directory in the cmake manual is as follows:

aux_source_directory(<dir> <variable>) 

This command assigns the <dir> all source file names to the <variable> parameter. The fourth line uses the command add_executable to indicate that the source file in the dir_srcs variable needs to be compiled into an executable file named main.

After compiling the file cmakelists.txt, you must use the cmake or ccmake command to generate the makefile. The difference between ccmake and cmake is that ccmake provides a graphical operation interface. The cmake command is executed as follows:

cmake [options] <path-to-source> 

Here we enter the directory where main. cpp is located and run "cmake." To Get The makefile and compile it using make, as shown in.

Figure 1. camke running result
 



Back to Top

How to process multiple source file directories

CMake Process source code pointsIt is also very simple to deploy in different directories. Now let's assume that our source codeThe distribution is as follows::

Figure 2. source code distribution
 

The files under the src directory must be compiled into a Linked Library.

Step 1: cmakelists.txt in the main directory of the project

Create the file cmakelists.txt in step 2. The file content is as follows:

Cmakelists.txt in step 2 in listing 3

1 PROJECT(main)2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 3 ADD_SUBDIRECTORY( src )4 AUX_SOURCE_DIRECTORY(. DIR_SRCS)5 ADD_EXECUTABLE(main ${DIR_SRCS}  )6 TARGET_LINK_LIBRARIES( main Test )

Compared with listing 2, this file adds the following content: the third line, use the command add_subdirectory to indicate that this project contains a sub-directory SRC. Line 6: run the target_link_libraries command to specify that the executable file main needs to connect to a linked library named test.

Step 2: cmakelists.txt In the subdirectory

Create cmakelists.txt In the SRC subdirectory. The file content is as follows:

Listing 4. cmakelists.txt In the src directory

1 AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)2 ADD_LIBRARY ( Test ${DIR_TEST1_SRCS})

Use the add_library command in this file to compile the source files in the src directory into a shared library.

Step 3: Execute cmake

Now we have completed the compilation of all the cmakelists.txt files in the project. Go to the directory Step 2 and execute the commands "cmake." and "make" in sequence. The result is as follows:

Figure 3. cmake execution result when processing multiple source file directories
 

During cmake execution, the cmakelists.txt in step 2 is parsed first. When the program executes the add_subdirectory (SRC) command, the src directory is used to parse the cmakelists.txt.

Find and use other library methods in the project

We will use some function libraries when developing software. These function libraries may be installed in different systems in different locations, during compilation, you must first find the header file of these software packages and the directory of The Link Library to generate compilation options. For example, if you want to use a bokeli database project, you need the header file db_cxx.h and the Link Library libdb_cxx.so. Now there is a source code file main. cpp in the project's root directory.

Step 1: Library description file

Create the directory cmake/modules/in the root directory of the project, and create the findlibdb_cxx.cmake file under cmake/modules/. The content is as follows:

Listing 5. File findlibdb_cxx.cmake

01 MESSAGE(STATUS "Using bundled Findlibdb.cmake...")02 03 FIND_PATH(04   LIBDB_CXX_INCLUDE_DIR05   db_cxx.h 06   /usr/include/ 07   /usr/local/include/ 08   )09 10 FIND_LIBRARY(11   LIBDB_CXX_LIBRARIES NAMES  db_cxx12   PATHS /usr/lib/ /usr/local/lib/13   )

The findlibdb_cxx.cmake file name must comply with the specification: findlibname. cmake, where name is the name of the function library. The findlibdb_cxx.cmake syntax is the same as that of cmakelists.txt. Three commands are used: Message, find_path, and find_library.

  • Command MESSAGE YesSet parametersContentOutput to Terminal
  • Command FIND_PATH Specifies the path to search for header files,The prototype is as follows: 
    find_path(<VAR> name1 [path1 path2 ...]) 
    The command in the Parameter path* Search for files in the specified directory name1 And save the searched path in the Variable VAR . List5The38The line indicates /usr/include/ And /usr/local/include/ Searching for filesdb_cxx.h ,And set db_cxx.h The path is saved in LIBDB_CXX_INCLUDE_DIR.
  • Command FIND_LIBRARY Same FIND_PATH Similar,Used to find the Linked Library and save the result in the variable. List5The1013The line indicates the Directory /usr/lib/ And /usr/local/lib/Search db_cxx Link Library,And save the result in LIBDB_CXX_LIBRARIES 

Step 2: cmakelist.txt in the project root directory

Create cmakelist.txt in the project root directory:

Listing 6. You can find the cmakelist.txt

01 PROJECT(main)02 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)03 SET(CMAKE_SOURCE_DIR .)04 SET(CMAKE_MODULE_PATH ${CMAKE_ROOT}/Modules ${CMAKE_SOURCE_DIR}/cmake/modules) 05 AUX_SOURCE_DIRECTORY(. DIR_SRCS)06 ADD_EXECUTABLE(main ${DIR_SRCS})07 08 FIND_PACKAGE( libdb_cxx REQUIRED)09 MARK_AS_ADVANCED(10 LIBDB_CXX_INCLUDE_DIR11 LIBDB_CXX_LIBRARIES12 )13 IF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)14 MESSAGE(STATUS "Found libdb libraries")15    INCLUDE_DIRECTORIES(${LIBDB_CXX_INCLUDE_DIR})16     MESSAGE( ${LIBDB_CXX_LIBRARIES} )17     TARGET_LINK_LIBRARIES(main ${LIBDB_CXX_LIBRARIES}18 )19 ENDIF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)

In this file, lines 4th indicate the findlibdb_cxx.cmake in the directory./cmake/modules, and lines 8-19 indicate the process of searching the Link Library and header files. Run the find_package command to find the findlibdb_cxx.cmake file in the directory indicated by cmake_module_path. Row 13-19 is a condition judgment statement, indicating that if libdb_cxx_include_dir and libdb_cxx_libraries are both assigned values, you need to set the header file to the keystore during compilation and set the executable file main to be connected to the libdb_cxx_libraries.

Step 3: Execute cmake

After findlibdb_cxx.cmake and cmakelist.txt are compiled, execute "cmake." and "make" in the root directory of the project. The result is shown in:

Figure 4. cmake execution results when other libraries are used
 

 

Use cmake to Generate debug and release programs

In Visual Studio, we can generate the debug and release programs, and use cmake to achieve the above results. Debugging information is required for the executable files generated by the project of the debug version, and optimization is not required for the release version. These features are determined by the compilation parameters in gcc/g ++. If the optimization degree is adjusted to the highest level, you need to set the parameter-O3. The lowest parameter is-O0, which means no optimization is performed; the parameter for adding debugging information is-g-ggdb. If this parameter is not added, the debugging information will not be included in the generated binary file.

Cmake has a variable cmake_build_type, which can be debug release relwithdebinfo and minsizerel. When the value of this variable is debug, cmake uses the strings in the variables cmake_cxx_flags_debug and cmake_c_flags_debug as the compilation options to generate makefile. When the value of this variable is release, the project uses the cmake_cxx_flags_release and cmake_c_flags_release variables to generate makefile.

Assume that there is only one file main. cpp in the project. Below is a cmakelist.txt program that can generate the debug and release versions:

Listing 7

1 PROJECT(main)2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)3 SET(CMAKE_SOURCE_DIR .)4 5 SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")6 SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")7 8 AUX_SOURCE_DIRECTORY(. DIR_SRCS)9 ADD_EXECUTABLE(main ${DIR_SRCS})

Two variables cmake_cxx_flags_debug and cmake_cxx_flags_release are set in lines 5th and 6, which are the compilation options for debug and release respectively. After editing cmakelist.txt, run the ccmake command to generate the makefile. Enter "ccmake." In the root directory of the project to enter a graphical interface, as shown in:

Figure 5. ccmake Interface
 

Follow the prompts on the page and press "c" to perform Configure. The page displays the cmake_build_type configuration variable. As shown in:

Figure 6. ccmake interface after configure is executed
 

Next, we will first generate the makefile for Debug: Set the variable cmake_build_type to debug, perform configure by "C", generate makefile by "g", and exit. Run the find * | xargs grep "O0" command and the result is as follows:

Listing 8 find * | xargs grep "O0" execution result

CMakeFiles/main.dir/flags.make:CXX_FLAGS = -O0 -Wall -g -ggdb CMakeFiles/main.dir/link.txt:/usr/bin/c++ -O0 -Wall -g -ggdb CMakeFiles/main.dir/main.cpp.o -o main -rdynamic CMakeLists.txt:SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")

The result shows that the generated makefile uses the variable cmake_cxx_flags_debug as the compile-time parameter.

Next we will generate the release makefile: Execute the "ccmake." command again to set the variable cmake_build_type to release, generate the makefile, and exit. Run the find * | xargs grep "O0" command and the result is as follows:

Listing 9 find * | xargs grep "O0" execution result

CMakeLists.txt:SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")

The result of executing the find * | xargs grep "O3" command is as follows:

Listing 10. Find * | xargs grep "O3" execution result

CMakeCache.txt:CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUGCMakeCache.txt:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUGCMakeFiles/main.dir/flags.make:CXX_FLAGS = -O3 -Wall CMakeFiles/main.dir/link.txt:/usr/bin/c++ -O3 -Wall CMakeFiles/main.dir/main.cpp.o -o main -rdynamic CMakeLists.txt:SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

The two results indicate that the generated makefile uses the variable cmake_cxx_flags_release as the compile-time parameter.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.