CMake Helloworld 02: a more practical Hello World CMake example, cmakehelloworld

Source: Internet
Author: User

CMake Helloworld 02: a more practical Hello World CMake example, cmakehelloworld

 

References:

Ref 1. CMake Practice-Cjacker;

 

We will use the out-of-source external build. The agreed build directory is the build self-recorded under the project directory.

The task in this section is to make the previous Hello World project more like a project. What we need to do is:

  • Add a subdirectory src for the project to place the project source code;
  • Uses a sub-directory docto deploy the project's file hello.txt
  • Add the text file COPYRIGHT and README in the project directory;
  • Add a runhello. sh script to the project directory to call the hello binary
  • Put the constructed target file into the bin subdirectory of the build directory;
  • Finally install these files: Convert the hello binary file with runhello. install sh to/usr/bin, and install the content in the doc directory and COPYRIGHT/README to/usr/share/doc/cmake/t2,

 

1. preparations:

Create the t2 directory under the/home/ccj/CMakeDemo/directory. Copy main.cand cmakelists.txt of the t1project to the t2 directory.

 

2. Add the subdirectory src:

Mkdir src

Mv main. c src

The current project looks like this:

 

In the following section, we will create a cmakelists.txt file for any of the directories,

Write the cmakelists.txt file as follows:

# T2/src/CMakeLists.txt

ADD_EXECUTABLE (hello main. c)

 

Modify cmakelists.txt of t2project:

# T2/CMakeLists.txt

PROJECT (HELLO)

ADD_SUBDIRECTORY (src bin)

Create the build directory and go to the build directory for external compilation.

Cmake ..

Make

The result is as follows:

 

 

After the build is complete, you will find that the generated target file hello is in the build/bin directory:

 

Syntax explanation:

ADD_SUBDIRECTORY command:

ADD_SUBDIRECTORY (source_dir [binary_dir] [EXCLUDE_FROM_ALL])

 

This command is used to add sub-directories for storing source files to the current project and specify the locations where the intermediate and target binary files are stored. The EXCLUDE_FROM_ALL parameter indicates that this directory is excluded from the compilation process. For example, the project example may need to be constructed separately after the project is built. (Of course, you can also solve this problem by defining dependencies ).

The preceding example defines adding the src subdirectory to the project and specifying the compiling output (including the intermediate compilation result) path as the bin directory. If the bin directory is not specified, the compilation results (including intermediate results) are stored in the build/src directory (that is, an src directory is automatically created under build, this directory corresponds to the original src directory). After specifying the bin directory, it is equivalent to renaming src to bin during compilation, all intermediate results and target binary data are stored in the build/bin directory.

 

The SUBDIRS command is used as follows: SUBDIRS (dir1 dir2. ..). However, this command is not recommended. It can add multiple subdirectories at a time, and the subdirectory system will still be saved even if it is compiled externally. If we change ADD_SUBDIRECTORY (src bin) to SUBDIRS (src) in the preceding example ). A src directory will appear in the build directory, and the generated target code hello will be stored in the src directory.

 

3. Save the destination binary in another place.

Whether it is the SUBDIRS or ADD_SUBDIRECTORY command (whether or not the compilation output directory is specified ), we can use the SET command to redefine the EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH variables to specify the final destination binary location (the final generated hello or shared library, excluding the intermediate files generated by compilation)

SET (EXECUTABLE_OUTPUT_PATH $ {PROJECT_BINARY_DIR}/bin)

SET (LIBRARY_OUTPUT_PATH $ {PROJECT_BINARY_DIR}/lib)

In section 1, we mentioned the <projectname> _ BINARY_DIR and PROJECT_BINARY_DIR variables, which refer to the current directory where compilation occurs. For internal compilation (in-source build ), PROJECT_SOURCE_DIR is the directory where the project code is located. If it is external compilation (out-of-source build), PROJECT_SOURCE_DIR refers to the external compilation directory, that is, the t2/build directory in this example. Therefore, the preceding two commands define:

The output path of the executable binary isBuild/binAnd the library output path isBuild/lib.

 

This section does not mention the construction of shared and static databases. Therefore, you can ignore the Second instruction. However, we should write this directive on the project's CMakeLists.txt or the CMakeLists.txt under the src directory to grasp a simple principle,WhereADD_EXECUTABLE or ADD_LIBRARY. If you need to change the target storage path, add the above definition to the directory.

In this example, cmakelists.txt under src, that is:

# Src/CMakeLists.txt

ADD_EXECUTABLE (hello main. cpp)

SET (EXECUTABLE_OUTPUT_PATH $ {PROJECT_BINARY_DIR }/)

 

After Run make, binary file hello is placed under t2/build, that is, t2/build/hello

 

You can change the directory as follows:

# Src/CMakeLists.txt

ADD_EXECUTABLE (hello main. cpp)

SET (EXECUTABLE_OUTPUT_PATH $ {PROJECT_BINARY_DIR}/bin)

 

After Run make, binary file hello is placed under t2/build/bin, that is, t2/build/bin/hello.

 

 

4. How to install it.

Two installation methods are required. One is to install the package directly after the code is compiled, and the other is to install the package in the specified directory.

Therefore, even the simplest manually written Makefile looks like this:

DESTDIR =

Install:

Mkdir-p $ (DESTDIR)/usr/bin

Install-m 755 hello $ (DESTDIR)/usr/bin

 

You can use:

Make install

Install hello directly to the/usr/bin directory, or use make install

DESTDIR =/tmp/test install it in the/tmp/test/usr/bin directory. This method is often used during packaging.

To be more complex, you also need to define the PREFIX. Generally, the autotools project runs the following command:

./Configure-prefix =/usr or./configure -- prefix =/usr/local to specify the PREFIX.

For example, the Makefile above can be rewritten:

DESTDIR =

PREFIX =/usr

Install:

Mkdir-p $ (DESTDIR)/$ (PREFIX)/bin

Install-m 755 hello $ (DESTDIR)/$ (PREFIX)/bin

 

So how should we install HelloWorld? Here we need to introduce a new cmake commandINSTALLAnd a very useful variableCMAKE_INSTALL_PREFIX.

The CMAKE_INSTALL_PREFIX variable is similar to the-prefix of the configure script. The common usage looks like this:

Cmake-DCMAKE_INSTALL_PREFIX =/usr.

 

The INSTALL command defines the installation rules. The installation content can include the target binary, dynamic library, static library, files, directories, scripts, and so on. The INSTALL command contains various installation types, which need to be explained separately:

 

1) install the target file:

INSTALL (TARGETSTargets...

[[ARCHIVE | LIBRARY | RUNTIME]

[DESTINATION <dir>]

[PERMISSIONS permissions...]

[Deployments [Debug | Release |...]

[COMPONENT <component>]

[OPTIONAL]

] [...])

The TARGETS parameter is followed by the target file defined through ADD_EXECUTABLE or ADD_LIBRARY, which may be executable binary, dynamic library, or static library. There are three types of targets. ARCHIVE refers to static LIBRARY, dynamic LIBRARY, and RUNTIME refers to executable binary. DESTINATION defines the installation path. If the path starts with "/", it indicates the absolute path. In this case, CMAKE_INSTALL_PREFIX is actually invalid. If you want CMAKE_INSTALL_PREFIX to define the installation path, you must write it as a relative path, that is, do not start with "/". Then, the installation path is $ {CMAKE_INSTALL_PREFIX}/<DESTINATION-defined path>;

 

A simple example:

INSTALL (TARGETS myrun mylib mystaticlib

Runtime destination bin

Library destination lib

Archive destination libstatic

)

In the above example, we will:

Run the binary myrun command to install it to the $ {CMAKE_INSTALL_PREFIX}/bin directory.

Install the dynamic library libmylib to the $ {CMAKE_INSTALL_PREFIX}/lib directory.

Install the static library libmystaticlib to the $ {CMAKE_INSTALL_PREFIX}/libstatic directory.

Note that you do not need to care about the specific path generated by TARGETS. You only need to write the TARGETS name.

 

2) Installation of common files:

INSTALL (FILESFiles... DESTINATION <dir>

[PERMISSIONS permissions...]

[Deployments [Debug | Release |...]

[COMPONENT <component>]

[RENAME <name>] [OPTIONAL])

It can be used to install common files and specify access permissions. The file name is the relative path under the path where the command is located.

If PERMISSIONS is not defined by default, the permission after installation is:

OWNER_WRITE, OWNER_READ, GROUP_READ, and WORLD_READ, which are 644 permissions.

 

3) executable program installation for non-target files (such as scripts ):

INSTALL (PROGRAMSFiles... DESTINATION <dir>

[PERMISSIONS permissions...]

[Deployments [Debug | Release |...]

[COMPONENT <component>]

[RENAME <name>] [OPTIONAL])

The only difference with the usage of the preceding FILES command is that the permission after installation is:

OWNER_EXECUTE, GROUP_EXECUTE, and WORLD_EXECUTE, that is, 755 permission

 

 

4) Directory installation:

INSTALL (DIRECTORYDirs... DESTINATION <dir>

[FILE_PERMISSIONS permissions...]

[DIRECTORY_PERMISSIONS permissions...]

[USE_SOURCE_PERMISSIONS]

[Deployments [Debug | Release |...]

[COMPONENT <component>]

[[PATTERN <pattern> | REGEX <regex>]

[EXCLUDE] [PERMISSIONS permissions...] [...])

Here we mainly introduce the DIRECTORY, PATTERN, and PERMISSIONS parameters.

DIRECTORY is connected to the relative path of the Source DIRECTORY. Note that abc and abc/are very different.

If the directory name does not end with a slash (/), the directory will be installed as the abc in the target path. If the directory name ends with a slash (/), the contents in the directory will be installed to the target path, this directory is not included.

PATTERN is used for filtering by regular expressions, and PERMISSIONS is used to specify the File Permission after PATTERN filtering.

Let's look at an example:

INSTALL (DIRECTORY icons scripts/DESTINATION share/myproj

PATTERN "CVS" EXCLUDE

PATTERN "scripts /*"

PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)

 

The execution result of this command is:

Install the icons directory to <prefix>/share/myproj, and install the content in scripts/to the <prefix>/share/myproj directory that does not contain the directory named CVS, specify the permission for the scripts/* file as OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.

 

Run the CMAKE script during installation:

INSTALL ([[SCRIPT <file>] [CODE <code>] [...])

The SCRIPT parameter is used to call the cmake SCRIPT file (that is, the <abc>. cmake file) during installation)

The CODE parameter is used to execute the CMAKE command and must be enclosed in double quotation marks. For example:

INSTALL (CODE "MESSAGE (\" Sample install message .\")")

There are several commands marked as obsolete, such as INSTALL_FILES. These commands are no longer recommended, so we will not repeat them here.

 

Next, we will rewrite our project file to support installation of various files, and we will use

CMAKE_INSTALL_PREFIX command.

 

5. Modify Helloworld to support installation.

At the beginning of this section, we define the following tasks:

  • Add a sub-directory src for the project to store the source code;
  • Use a sub-directory docto store the project file hello.txt
  • Add the text file COPYRIGHT and README in the project directory;
  • Add a runhello. sh script to the project directory to call the hello binary
  • Put the constructed target file into the bin subdirectory of the build directory;
  • Finally install these files: Install the hello binary and runhello. sh to/<prefix>/bin, and install hello.txt and COPYRIGHT/readme in the doccatalog to/<prefix>/share/doc/cmake/t2,

 

1) First, add the appeal file:

 

Cd/backup/cmake/t2

Mkdir doc

Vi doc/hello.txt # Enter some content and save it

 

 

 

2. Change the cmakelists.txt file of each directory to the following:

1. install COPYRIGHT/readme, directly modify the main project file cmakelists.txt, and add the following command:

INSTALL (files copyright readme destination share/doc/cmake/t2)

2. Install runhello.sh and directly modify the main project file cmakelists.txt. Add the following command:

INSTALL (PROGRAMS runhello. sh DESTINATION bin)

Install hello, modify t2/src/CMakeLists.txt, and add the following command:

INSTALL (TARGETS hello runtime destination bin)

3. Install hello.txt in doc2. there are two methods: one is to create cmakelists.txt in docdirectory and add the doc directory to the project through ADD_SUBDIRECTORY. Another way is to directly INSTALL (DIRECTORY…) in the project DIRECTORY ...) To complete, the former is relatively simple, you can do it based on your interests, we will try the latter, by the way, demonstrate the installation of the following DIRECTORY. Because hello.txt is to be installed in/<prefix>/share/doc/cmake/t2, we cannot directly install the entire doc directory. The method used here is to install the content in the doc directory, that is, use "doc/" to add the following content to the project file cmakelists.txt:

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

 

6. Try to modify the result:

Now go to the build directory for external compilation. Note that the CMAKE_INSTALL_PREFIX parameter is used. Here we

Install it in the/tmp/t2 directory:

Cmake-DCMAKE_INSTALL_PREFIX =/tmp/t2/usr ..

Then run

Make

Make install

This result will be shown as below:

 

 

Let's go to the/tmp/t2 directory and check the installation result:

 

Now we can run the binary file-hello in two different directories, and we can get the same results.

 

 

If you want to install it directly to the system, run the following command:

Cmake-DCMAKE_INSTALL_PREFIX =/usr ..

 

7. One question

Where will I install CMAKE_INSTALL_PREFIX if it is not defined?

You can try the following, cmake...; make; sudo make install, you will find

The default definition of CMAKE_INSTALL_PREFIX is/usr/local.

 

8. Summary:

This section describes how to use multiple directories, various installation instructions, and CMAKE_INSTALL_PREFIX variables in the project.


What is the difference between Opencv compilation and Cmake? What is Cmake used? It's better to be more popular,

Cmake is a make tool that can call you and the compiler to compile and link multiple files based on the makefile file. Cmake is used to compile and generate those files using your local compiler.

A cmake error occurs when you install tpm emulator.

Cmake uses makefile

Let's see this sentence: Maid: all warnings being treated as errors

You need to remove-Werror from CFLAGS, CPPFLAGS etc.; these are usually set in Makefile's or build scripts.
 

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.