当前位置:网站首页>Cmake notes

Cmake notes

2022-07-23 14:48:00 Chaoying.

I didn't write this blog post myself , yes B Stand on one CMake Supporting materials for the introductory tutorial , Personally, I think this tutorial is very suitable for me to use g++ Introduction to Xiaobai , Put a link here Liu Beisi : Detailed introduction from zero CMake, I strongly recommend that you want to learn CMake Go and have a look . There is a tutorial at the end of the article Up Lord's reward QR code , Not my own , Those with strength can support this Up Lord

CMake

explain

cmake What is the definition of ?----- Advanced compilation configuration tool

When multiple people develop a project in different languages or compilers , Finally, output an executable file or shared library (dll,so wait ) Then the artifact appeared -----CMake!

All operations are compiled CMakeLists.txt To complete — Simple

Officer, Fang's website is www.cmake.org, You can get more information about cmake Information about

Study CMake Purpose , Handling large for the future C/C++/JAVA Project preparation

CMake install

1、 Most of linux The system has been installed CMake

2、Windows Or some not installed linux System , Go to http://www.cmake.org/HTML/Download.html You can download and install

CMake One HelloWord

1、 Step one , Write a HelloWord

#main.cpp

#include <iostream>

int main(){
    
std::cout <<  "hello word" << std::endl;
}

2、 Step two , Write CMakeLists.txt

#CMakeLists.txt

PROJECT (HELLO)

SET(SRC_LIST main.cpp)

MESSAGE(STATUS "This is BINARY dir " ${
    HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${
    HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${
    SRC_LIST})

3、 Step three 、 Use cmake, Generate makefile file

cmake .

 Output :
[[email protected] cmake]# cmake .
CMake Warning (dev) in CMakeLists.txt:
  Syntax Warning in cmake code at

    /root/cmake/CMakeLists.txt:7:37

  Argument not separated from preceding token by whitespace.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- This is BINARY dir /root/cmake
-- This is SOURCE dir /root/cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /root/cmake

These files are generated in the directory -CMakeFiles, CMakeCache.txt, cmake_install.cmake Wait for the documents , And generated Makefile.
Now we need to ignore the role of these documents , You can ignore it later . The key is , It automatically generates Makefile.

4、 Use make Command compilation

[email protected] cmake]# make
Scanning dependencies of target hello
[100%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
Linking CXX executable hello
[100%] Built target hello

5、 And you end up with Hello Executable program of

CMake One HelloWord- The grammar of

PROJECT keyword

It can be used to specify the name of the project and the supported language , All languages are supported by default

PROJECT (HELLO) Specifies the name of the project , And support all languages — Suggest

PROJECT (HELLO CXX) Specifies the name of the project , And the supported language is C++

PROJECT (HELLO C CXX) Specifies the name of the project , And the supported language is C and C++

This assignment implicitly defines two CMAKE The variable of

_BINARY_DIR, In this case, it is HELLO_BINARY_DIR

_SOURCE_DIR, In this case, it is HELLO_SOURCE_DIR

MESSAGE Keyword can directly use two variables , Currently all point to the current working directory , We will talk about external compilation later

problem : If the project name is changed , The names of these two variables will also change

solve : Two more predefined variables are defined :PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR, These two variables and HELLO_BINARY_DIR,HELLO_SOURCE_DIR It's consistent . So it doesn't matter to change the project name

SET keyword

Of the specified variable used to display

SET(SRC_LIST main.cpp) SRC_LIST Variables contain main.cpp

It's fine too SET(SRC_LIST main.cpp t1.cpp t2.cpp)

MESSAGE keyword

Output user-defined information to the terminal

It mainly contains three kinds of information :

  • SEND_ERROR, Make a mistake , The generation process was skipped .
  • SATUS, The output prefix is — Information about .
  • FATAL_ERROR, Terminate all... Immediately cmake The process .

ADD_EXECUTABLE keyword

Generate executable files

ADD_EXECUTABLE(hello ${SRC_LIST}) The generated executable file name is hello, Read variables from the source file SRC_LIST The content in

You can also write directly ADD_EXECUTABLE(hello main.cpp)

The above example can be simplified as

PROJECT(HELLO)
ADD_EXECUTABLE(hello main.cpp)

Be careful : Project name HELLO And the generated executable hello It doesn't matter

Basic principles of grammar

  • Variable usage ${} Method value , But in IF The variable name is used directly in the control statement

  • Instructions ( Parameters 1 Parameters 2…) Parameters are enclosed in brackets , Parameters are separated by spaces or semicolons . On the surface of the above ADD_EXECUTABLE Instruction as an example , If there is another func.cpp Source file

    It's about to be written :ADD_EXECUTABLE(hello main.cpp func.cpp) perhaps ADD_EXECUTABLE(hello main.cpp;func.cpp)

  • Instructions are case independent , Parameters and variables are case dependent . but , It is recommended that you use all uppercase commands

Grammar notes

  • SET(SRC_LIST main.cpp) It can be written. SET(SRC_LIST “main.cpp”), If the source file name contains spaces , You have to put double quotes
  • ADD_EXECUTABLE(hello main) Suffix OK no , He will automatically find .c and .cpp, It's better not to write like this , There may be these two files main.cpp and main

Internal build and external build

  • The above example is an internal build , He produces a lot of temporary documents , Inconvenient to clean
  • External build , Will put the generated temporary files in build Under the table of contents , It will not have any impact on the source file. It is strongly built by external methods

Examples of external construction methods

// Example directory ,CMakeLists.txt Consistent with the above example 
[[email protected] cmake]# pwd
/root/cmake
[[email protected] cmake]# ll
total 8
-rw-r--r--. 1 root root 198 Dec 28 20:59 CMakeLists.txt
-rw-r--r--. 1 root root  76 Dec 28 00:18 main.cpp

1、 Build a build Catalog , It can be anywhere , It is suggested that the current directory

2、 Get into build, function cmake … Of course … Represents the directory above , You can write CMakeLists.txt The absolute path , The production documents are in build The directory

3、 stay build Under the table of contents , function make To build the project

Notice the two variables built externally

1、HELLO_SOURCE_DIR Or engineering path

2、HELLO_BINARY_DIR Compile path That is to say /root/cmake/bulid

Give Way Hello World It looks more like a project

  • Add a subdirectory to the project src, Used to place engineering source code
  • Add a subdirectory doc, The document used to place the project hello.txt
  • Add a text file to the project directory COPYRIGHT, README
  • Add a runhello.sh Script , Used to call hello Binary system
  • Put the built object file into the bin subdirectories
  • take doc Catalog and COPYRIGHT/README The installation to /usr/share/doc/cmake/

Put the target file in the... Of the build directory bin subdirectories

There should be one under each directory CMakeLists.txt explain

[[email protected] cmake]# tree
.
├── build
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    └── main.cpp

Outer layer CMakeLists.txt

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

src Under the CMakeLists.txt

ADD_EXECUTABLE(hello main.cpp)

ADD_SUBDIRECTORY Instructions

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

  • This command is used to add a subdirectory for storing source files to the current project , And you can specify the location where the intermediate binary and the target binary are stored

  • EXCLUDE_FROM_ALL The function is to exclude the written directory from compilation , As in the program example

  • ADD_SUBDIRECTORY(src bin)

    take src Add the subdirectory to the project and specify the compilation output ( Contains intermediate results of compilation ) Path is bin Catalog

    If not bin The designation of the directory , So the compilation results ( Including intermediate results ) Will be stored in build/src Catalog

Change the binary save path

SET Instruction redefines EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH Variable To specify the location of the final target binary

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

reflection : Load which CMakeLists.txt among

Where to change the target storage path , Where to add the above definition , So it should be src Under the CMakeLists.txt The write

install

  • One is to compile the code directly make install install
  • One is to specify when packing Directory installation .
    • Simply specify the directory like this :make install DESTDIR=/tmp/test
    • A little more complicated, you can specify the directory like this :./configure –prefix=/usr

How to install HelloWord

Use CMAKE A new instruction :INSTALL

INSTALL The installation of can include : Binary system 、 Dynamic library 、 Static libraries and files 、 Catalog 、 Script etc.

Use CMAKE A new variable :CMAKE_INSTALL_PREFIX

//  Tree structure 
[[email protected] cmake]# tree
.
├── build
├── CMakeLists.txt
├── COPYRIGHT
├── doc
│   └── hello.txt
├── README
├── runhello.sh
└── src
    ├── CMakeLists.txt
    └── main.cpp

3 directories, 7 files

The installation files COPYRIGHT and README

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)

FILES: file

DESTINATION:

1、 Write absolute path

2、 You can write relative paths , Relative path actual path is :${CMAKE_INSTALL_PREFIX}/<DESTINATION Defined path >

CMAKE_INSTALL_PREFIX The default is in /usr/local/

cmake -DCMAKE_INSTALL_PREFIX=/usr stay cmake When it's time to specify CMAKE_INSTALL_PREFIX The path of the variable

set up script runhello.sh

PROGRAMS: Executable installation of non target files ( Like scripts and so on )

INSTALL(PROGRAMS runhello.sh DESTINATION bin)

explain : The actual installation is /usr/bin

install doc Medium hello.txt

  • One 、 It is through doc Directory establishment CMakeLists.txt , adopt install Under the file

  • Two 、 It's directly in the project directory through

    INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)

DIRECTORY What's connected behind is where Source Relative path to directory

Be careful :abc and abc/ There's a big difference

The directory name does not start with / ending : This directory will be installed as... Under the target path

The directory name is as follows / ending : Install the contents of this directory to the target path

setup script

cmake …

make

make install

Construction of static library and dynamic library

Mission :

1, Build a static library and a dynamic library , Provide HelloFunc Functions are used by other programs ,HelloFunc Output to the terminal Hello World character string .

2, Install header files and shared libraries .

The difference between static library and dynamic library

  • The extension of a static library is generally “.a” or “.lib”; The extension of the dynamic library is generally “.so” or “.dll”.
  • Static libraries are directly integrated into the target program at compile time , The compiled executable can run independently
  • The dynamic library will not be put into the connected target program at compile time , Executable files cannot be run alone .

Some functions are needed in many places , In order to save storage space, only one copy is enough , Call and execute when necessary , So you can use dynamic library , But some function codes only need one or a few programs , Therefore, you can directly compile it when compiling , At this point, you should use the static library . In short, whether it is compiled into a static library or a dynamic library mainly depends on whether this part of the code will be used in many places

Build instance

[[email protected] cmake2]# tree
.
├── build
├── CMakeLists.txt
└── lib
    ├── CMakeLists.txt
    ├── hello.cpp
    └── hello.h

hello.h The content in

#ifndef HELLO_H
#define Hello_H

void HelloFunc();

#endif

hello.cpp The content in

#include "hello.h"
#include <iostream>
void HelloFunc(){
    
    std::cout << "Hello World" << std::endl;
}

In the project cmake Content

PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)

lib in CMakeLists.txt The content in

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${
    LIBHELLO_SRC})

ADD_LIBRARY

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

  • hello: It's a normal library name , The generated name will be preceded by lib, The resulting file is libhello.so
  • SHARED, Dynamic library STATIC, Static library
  • ${LIBHELLO_SRC} : Source file

Build both static and dynamic libraries

//  If in this way , Only one dynamic library will be built , Will not build static libraries , Although the suffix of the static library is .a
ADD_LIBRARY(hello SHARED ${
    LIBHELLO_SRC})
ADD_LIBRARY(hello STATIC ${
    LIBHELLO_SRC})

//  Modify the name of the static library , This is OK , But we often want their names to be the same , Just different suffixes 
ADD_LIBRARY(hello SHARED ${
    LIBHELLO_SRC})
ADD_LIBRARY(hello_static STATIC ${
    LIBHELLO_SRC})

SET_TARGET_PROPERTIES

This command can be used to set the name of the output , For dynamic libraries , It can also be used to specify the dynamic library version and API edition

Build both static and dynamic libraries

SET(LIBHELLO_SRC hello.cpp)

ADD_LIBRARY(hello_static STATIC ${
    LIBHELLO_SRC})

// Yes hello_static Your duplicate name is hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES  OUTPUT_NAME "hello")
//cmake  Building a new target  when , Will try to clean up other libraries using this name , because , In the build  libhello.so  when ,  It's going to clean up  libhello.a
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

ADD_LIBRARY(hello SHARED ${
    LIBHELLO_SRC})

SET_TARGET_PROPERTIES(hello PROPERTIES  OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

Version number of dynamic library

Generally, dynamic libraries have a version number Association

libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2

CMakeLists.txt Insert the following

SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

VERSION Refers to the dynamic library version ,SOVERSION Refer to API edition .

Install shared libraries and header files

In this case, we will hello The shared library of is installed to /lib Catalog ,

take hello.h The installation to /include/hello Catalog

// Put the file in this directory 
INSTALL(FILES hello.h DESTINATION include/hello)

// Binary system , Static library , Dynamic libraries are installed with TARGETS
//ARCHIVE  Specifically static libraries ,LIBRARY  Specifically dynamic library ,RUNTIME  The executable target binary .
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

Be careful :

During installation , Specify the path , Put it under the system

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

Use external shared libraries and header files

preparation , Create a new directory to use external shared libraries and header files

[[email protected]-R4CM-srv cmake3]# tree
.
├── build
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    └── main.cpp

main.cpp

#include <hello.h>

int main(){
    
	HelloFunc();
}

solve :make The problem that the following header file cannot be found

PS:include <hello/hello.h> such include Yes. , In doing so , There's nothing to say

keyword :INCLUDE_DIRECTORIES This command can be used to add multiple specific header search paths to a project , The paths are separated by spaces

stay CMakeLists.txt Add header file search path to

INCLUDE_DIRECTORIES(/usr/include/hello)

thank :

Net friend :zcc720 Reminder

solve : Find the referenced function problem

Error message :undefined reference to `HelloFunc()’

keyword :LINK_DIRECTORIES Add non-standard search paths for shared libraries

Specify the path where the third-party library is located ,LINK_DIRECTORIES(/home/myproject/libs)

keyword :TARGET_LINK_LIBRARIES Add shared libraries that need to be linked

TARGET_LINK_LIBRARIES When , Just give the name of the dynamic link library .

stay CMakeLists.txt Insert linked shared library in , Mainly inserted in executable Behind

see main Link status of

[[email protected]-R4CM-srv bin]# ldd main 
	linux-vdso.so.1 =>  (0x00007ffedfda4000)
	libhello.so => /lib64/libhello.so (0x00007f41c0d8f000)
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f41c0874000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f41c0572000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f41c035c000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f41bff8e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f41c0b7c000)

Link static libraries

TARGET_LINK_LIBRARIES(main libhello.a)

Special environment variables CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH

Be careful : These two are environment variables, not cmake Variable , Can be in linux Of bash Set in

We used the absolute path in the above example INCLUDE_DIRECTORIES(/usr/include/hello) To indicate include The location of the path

There's another way we can use it , Using environment variables export CMAKE_INCLUDE_PATH=/usr/include/hello

Add : production debug Version method :
cmake … -DCMAKE_BUILD_TYPE=debug

Ben ⼈ All videos and notes are free to share with ⼤ Family , Making videos and notes costs ⼤ The time cost of quantity

I have ⽼ Mother and child ⼦ To support , Please audience ⽼ Men have economic reality ⼒ A little reward ⼀ Next ⼩ brother , But don't force , Again ⼀ Thanks again .
Your reward , It will make me more ⼤ The movement of ⼒, Make better videos , thank ⼤ Family ⽀ a

Untitled

原网站

版权声明
本文为[Chaoying.]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/204/202207230921420953.html