<< Modern CMake >> translation 2. CMake basis

<< Modern CMake >> translation 2. CMake basis

Minimum version

This is every  CMakeLists.txt first line of the file. CMakeLists.txt CMake is required to Profile Name:

cmake_minimum_required(VERSION 3.1)

We come to understand that CMake syntax. Command names  cmake_minimum_required are not case sensitive, so it is common practice to use lowercase. 1  where VERSION is required by the special key command. The version number immediately after the VERSION keyword. Like anywhere else in this book, you simply click on the command name to link to the official document, and then use the drop-down list to switch between different versions of CMake documentation.

This line is very special! 2  version also pointed out the changes in behavior of CMake. So, if you set  minimum_required to  VERSION 2.8on macOS you will get the wrong link behavior, for example, in the latest version of CMake is true. If you put the version is set to 3.3 or lower, you will get the wrong symbols hidden behavior, and so on. In  policies  have a strategy and a version of the list.

In CMake 3.12, you can write to specify a range of versions CMake support, for example  VERSION 3.1...3.12; this means that you support a minimum 3.1, and also tested and support to the new policy 3.12. This is good for users who need a better set of terms, and due to the skills in grammar, it is backwards compatible with older versions of CMake (although the actual run CMake 3.2-3.11 only set the 3.1 version of the policy in this example). The new version of the policy is often the most important for macOS and Windows users, they usually have the latest version of CMake.

The new project should be written:

cmake_minimum_required(VERSION 3.1...3.15)

if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) endif() 

If CMake version is less than 3.12, the if block will be true, and the policy will be set to the current version of CMake. If CMake is 3.12 or higher, if blocks will be false, this time the new syntax  cmake_minimum_required will work, it will be able to work properly!

Warning: MSVC of CMake server model originally had this format when reading a  bug , so if you need to support legacy non-MSVC command line version of Windows, you will need to do the following:

cmake_minimum_required(VERSION 3.1)

if(${CMAKE_VERSION} VERSION_LESS 3.15) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) else() cmake_policy(VERSION 3.15) endif() 

 

 

If you do need to set a lower version here, you can use  cmake_policy conditional increase policy level or set a specific policy. Do this for at least your macOS user!

 

Setting project

Now, each top CMake file ( CMakeLists.txt) has the following line:

project(MyProject VERSION 1.0
                  DESCRIPTION "非常出色的项目"
                  LANGUAGES CXX)

Now we see more new syntax. String surrounded by quotation marks, space can be more or less, the project name is the first parameter (position parameter). All keyword arguments here are optional. By  VERSION parameters, which set a bunch of variables, such as  MyProject_VERSION and  PROJECT_VERSIONLANGUAGE It can be a C, CXX, Fortran and CUDA (CMake 3.7+). C CXX is the default. In the CMake 3.9, DESCRIPTION add in settings description of the project. You can refer to  project this document.

 

 

You can use  # to add at the beginning of  a comment . CMake also has inline annotation syntax, but is rarely needed, because the space is not important.

 

Project Name nothing special. At this time, do not add any goal.

Executable file

Although the link library more interesting, we usually generate most of their time in libraries, but here we want a simple executable file to begin.

add_executable(one two.cpp three.h)

Here are a few things to note. one Is the name of the executable file generated CMake the name of the target is also created (I guarantee that you will soon hear a lot of information about the target). Immediately after the executable file name of the source file list, you can list a list of any number of source files as needed. CMake is very smart, based on the source file name correctly identify the file extension, so the header file in the list will be CMake understood and ignored. Most of the time, the only reason we list the header files in the source file list is to have them appear in the IDE. For more information about common goals and build system, see  buildsystem .

Generating link library

Use  add_library generate link library, it is very simple:

add_library(one STATIC two.cpp three.h)

You can select the type of link library: STATIC, SHARED or MODULE. If no, CMake based variable  BUILD_SHARED_LIBS selection between STATIC and SHARED value.

As you will see in the next section that typically you need to create a pseudo-objective, which is a target not need to compile any file, for example, to include only library header files. This can also be referred to as INTERFACE library; the only difference is the interface with the library can not name the file.

You can also use an existing link library to generate a  ALIAS link library, which simply provide the name of the new target for you. One benefit of this is that you can create a name with  :: link library (see later). 3

Configure the build target

Now that we have specified the target, then how do we add to it the relevant information about it? For example, it may take a  include directory:

target_include_directories(one PUBLIC include)

target_include_directories The  include directory to the target.  PUBLIC Executable files is of little significance; for a link library that lets CMake know of any links to this goal must also contain the target directory. Other options are  PRIVATE(only affect the current target, without affecting the dependencies) and  INTERFACE(dependent on the required item only).

Now, we can target in series:

add_library(another STATIC another.cpp another.h)
target_link_libraries(another PUBLIC one)

target_link_libraries CMake is probably the most useful and most confusing command. It requires a target (another) and add a dependency target item. If the called  one destination does not exist, it will add a point on the path is called  one link library (ie, the name of the command). Or you can give it a complete link library path. Or linker flags. Finally, there is something a little confusing, and that is the classic CMake allows you to ignore keyword  PUBLIC, and so on. If the target has been completed link, try to mix styles in the chain further, you will receive an error.

Focuses on the use of targets and keywords in any place, that's right.

Target can contain directories, link libraries (or link target) compiler option, the compiler definition, compiler features (see section C 11 ++) and so on. As you will see in the two chapters that include project, you can usually use the target (and always make goals) to represent all libraries you use. Even if that is not the real link library, such as OpenMP, it can also be expressed in the target. This is the modern CMake great reason!

He started working practice

See if you can understand the following file operations. It creates a simple C ++ 11 libraries and a program to use it. No dependencies. I will discuss later use CMake 3.8 system more C ++ standard options.

cmake_minimum_required(VERSION 3.8)

project(Calculator LANGUAGES CXX)

add_library(calclib STATIC src/calclib.cpp include/calc/lib.hpp) target_include_directories(calclib PUBLIC include) target_compile_features(calclib PUBLIC cxx_std_11) add_executable(calc apps/calc.cpp) target_link_libraries(calc PUBLIC calclib) 
1. In this book, I will try to avoid showing you the wrong way of doing things; you can find many examples of this on the Internet. I occasionally mention an alternative approach, but unless absolutely necessary, otherwise these are not recommended. Usually they just help you read the older CMake code.  ↩
2. You sometimes see  FATAL_ERROR in CMake <2.6 version, you need to use it to support fail, now no longer needed.
3.  ::  syntax originally used to generate  INTERFACE IMPORTED  libraries, however, because of this, most of the  target_*  commands are not applicable to  IMPORTED  libraries. This makes them difficult to set their own. So now do not use  IMPORTED  keywords, use the  ALIAS  member target; it can work before you export destination. This limit has been fixed in CMake 3.11 in.  ↩

Guess you like

Origin www.cnblogs.com/hejiang/p/11247625.html