title: CMake Practice IV: install, test and add environment to generate installation package
categories: [actual combat iv]
tags:[CMake]
date: 2021/12/24
Author: hackett
WeChat official account: overtime ape
1. Installation test
CMake can also specify installation rules and add tests. These two functions can be performed by using make install and make test after generating the makefile. In GNU Makefile, you may need to write install and test pseudo targets and corresponding rules for this, but in CMake, such work also needs to simply call a few commands.
1.1 custom installation rules
First, in math / cmakelists Add the following two lines to the txt file:
# Specify the installation path of the MathFunctions library install (TARGETS MathFunctions DESTINATION bin) install (FILES MathFunctions.h DESTINATION include)
Indicates the installation path of the MathFunctions library. After that, also modify the CMakeLists file in the root directory and add the following lines at the end:
# Specify the installation path install (TARGETS Demo DESTINATION bin) install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
Through the above customization, the generated Demo file and MathFunctions library libmathfunctions O files will be copied to / usr/local/bin, and MathFunctions H and generated config The H file is copied to / usr/local/include. We can verify (incidentally, / usr/local / here is the root directory of the default installation. You can specify which root directory these files should be copied to by modifying the value of CMAKE_INSTALL_PREFIX variable):
[root@hackett demo5]# make install Consolidate compiler generated dependencies of target MathFunctions [ 50%] Built target MathFunctions Consolidate compiler generated dependencies of target demo [100%] Built target demo Install the project... -- Install configuration: "" -- Installing: /usr/local/bin/demo -- Installing: /usr/local/include/config.h -- Installing: /usr/local/bin/libMathFunctions.a -- Installing: /usr/local/include/myMath.h [root@hackett demo5]# ls /usr/local/bin/ demo libMathFunctions.a [root@iZwz97bu0gr8vx0j8l6kkzZ demo5]# ls /usr/local/include/ config.h myMath.h
1.2 project addition test
Adding tests is also simple. CMake provides a testing tool called CTest. All we have to do is to call a series of add_ in the CMakeLists file of the project root directory. Test command.
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) # set the project name project(demo5) # Add a configuration header file to handle CMake's settings for the source code configure_file ( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ) # Do you want to use your own MathFunctions library option (USE_MYMATH "Use provided math implementation" ON) # Add MathFunctions library if (USE_MYMATH) include_directories ("${PROJECT_SOURCE_DIR}/math") add_subdirectory (math) set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) endif (USE_MYMATH) aux_source_directory(. DIR_SRCS) # Specify build target add_executable(demo ${DIR_SRCS}) target_link_libraries(demo ${EXTRA_LIBS}) # Specify the installation path install (TARGETS demo DESTINATION bin) install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include) enable_testing() # Test whether the program runs successfully add_test (test_run demo 3 2) add_test (test_35_2 demo 35 2) set_tests_properties (test_35_2 PROPERTIES PASS_REGULAR_EXPRESSION "37") add_test (test_5_2 demo 5 2) set_tests_properties (test_5_2 PROPERTIES PASS_REGULAR_EXPRESSION "7") add_test (test_2_3 demo 2 3) set_tests_properties (test_2_3 PROPERTIES PASS_REGULAR_EXPRESSION "5")
The above code contains four tests. First test_run is used to test whether the program runs successfully and returns a value of 0. The remaining three tests are used to test whether 35 + 2, 5 + 2 and 2 + 3 can get the correct results. Where PASS_REGULAR_EXPRESSION is used to test whether the output contains the following string.
Test results:
[root@hackett demo5]# make Consolidate compiler generated dependencies of target MathFunctions [ 50%] Built target MathFunctions Consolidate compiler generated dependencies of target demo [ 75%] Building CXX object CMakeFiles/demo.dir/main.cpp.o [100%] Linking CXX executable demo [100%] Built target demo [root@hackett demo5]# make test Running tests... Test project /root/workspace/cmake/demo5 Start 1: test_run 1/4 Test #1: test_run ......................... Passed 0.00 sec Start 2: test_35_2 2/4 Test #2: test_35_2 ........................ Passed 0.00 sec Start 3: test_5_2 3/4 Test #3: test_5_2 ......................... Passed 0.00 sec Start 4: test_2_3 4/4 Test #4: test_2_3 ......................... Passed 0.00 sec 100% tests passed, 0 tests failed out of 4 Total Test time (real) = 0.01 sec
If you want to test more input data, writing test cases one by one like the above is too cumbersome. This can be achieved by writing macros:
# Define a macro to simplify testing macro (do_test arg1 arg2 result) add_test (test_${arg1}_${arg2} demo ${arg1} ${arg2}) set_tests_properties (test_${arg1}_${arg2} PROPERTIES PASS_REGULAR_EXPRESSION ${result}) endmacro (do_test) # Use this macro for a series of data tests do_test (35 2 "37") do_test (5 52 "7") do_test (2 3 "5")
For more detailed usage of CTest, you can refer to the CTest documentation through man 1 ctest.
2. Add version number
First modify the top-level CMakeLists file and add the following two lines after the project command:
set (Demo_VERSION_MAJOR 1) set (Demo_VERSION_MINOR 0)
Specify the major version number and minor version number of the current project respectively.
After that, in order to get the version information in the code, we can modify it config.h.in File, add two predefined variables:
// the configured options and settings for Tutorial #define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@ #define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
In this way, the version information can be printed directly in the code:
#include <stdio.h> #include <stdlib.h> #include "config.h" #ifdef USE_MYMATH #include "math/myMath.h" #else #include <math.h> #endif int sub(int a, int b) { return (a - b); } int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: %s argv[1] argv[2] \n", argv[0]); return 1; } printf("version : %d.%d\n", Demo_VERSION_MAJOR, Demo_VERSION_MINOR); int a = atof(argv[1]); int b = atoi(argv[2]); #ifdef USE_MYMATH printf("Now we use our own Math library. \n"); int result = add(a, b); printf("%d + %d = %d\n", a, b, result); #else printf("Now we use the main.cpp sub function. \n"); int result = sub(a, b); printf("%d - %d = %d\n", a, b, result); #endif return 0; }
Operation results:
[root@hackett demo7]# cmake . -- Configuring done -- Generating done -- Build files have been written to: /root/workspace/cmake/demo7 [root@hackett demo7]# make Consolidate compiler generated dependencies of target MathFunctions [ 25%] Building CXX object math/CMakeFiles/MathFunctions.dir/myMath.cpp.o [ 50%] Linking CXX static library libMathFunctions.a [ 50%] Built target MathFunctions [ 75%] Building CXX object CMakeFiles/demo.dir/main.cpp.o [100%] Linking CXX executable demo [100%] Built target demo [root@hackett demo7]# ./demo 2 3 version : 1.0 Now we use our own Math library. 2 + 3 = 5
3. Generate installation package
How to configure and generate installation packages on various platforms, including binary installation packages and source installation packages. In order to complete this task, we need to use CPack, which is also a tool provided by CMake for packaging.
First, cmakelists Add the following lines at the end of the txt file:
# Build a CPack installation package include (InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}") set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}") include (CPack)
The above code does the following work:
- Import the InstallRequiredSystemLibraries module to import the CPack module later;
- Set some CPack related variables, including copyright information and version information. The version information uses the version number defined in the previous section;
- Import the CPack module.
Create a ` license Txt file
touch License.txt
The next work is to build the project as usual and execute the cpack command.
- Generate binary installation package:
cpack -C CPackConfig.cmake
- Generate source installation package
cpack -C CPackSourceConfig.cmake
We can try. After the project is generated, execute cpack - C cpackconfig Cmake command:
[root@hackett demo8]# cmake . -- Configuring done -- Generating done -- Build files have been written to: /root/workspace/cmake/demo8 [root@hackett demo8]# cpack -C CPackConfig.cmake CPack: Create package using STGZ CPack: Install projects CPack: - Run preinstall target for: demo8 CPack: - Install project: demo8 [CPackConfig.cmake] CPack: Create package CPack: - package: /root/workspace/cmake/demo8/demo8-1.0.1-Linux.sh generated. CPack: Create package using TGZ CPack: Install projects CPack: - Run preinstall target for: demo8 CPack: - Install project: demo8 [CPackConfig.cmake] CPack: Create package CPack: - package: /root/workspace/cmake/demo8/demo8-1.0.1-Linux.tar.gz generated. CPack: Create package using TZ CPack: Install projects CPack: - Run preinstall target for: demo8 CPack: - Install project: demo8 [CPackConfig.cmake] CPack: Create package CPack: - package: /root/workspace/cmake/demo8/demo8-1.0.1-Linux.tar.Z generated. [root@hackett demo8]# ls CMakeCache.txt cmake_install.cmake config.h CPackConfig.cmake CPackSourceConfig.cmake demo demo8-1.0.1-Linux.tar.gz install_manifest.txt main.cpp math CMakeFiles CMakeLists.txt config.h.in _CPack_Packages CTestTestfile.cmake demo8-1.0.1-Linux.sh demo8-1.0.1-Linux.tar.Z License.txt Makefile
The three binary package files contain exactly the same content. We can execute one of them. An interactive installation interface automatically generated by CPack will appear:
[root@hackett demo8]# sh demo8-1.0.1-Linux.sh demo8 Installer Version: 1.0.1, Copyright (c) Humanity This is a self-extracting archive. The archive will be extracted to: /root/workspace/cmake/demo8 If you want to stop extracting, please press <ctrl-C>. Do you accept the license? [yn]: y By default the demo8 will be installed in: "/root/workspace/cmake/demo8/demo8-1.0.1-Linux" Do you want to include the subdirectory demo8-1.0.1-Linux? Saying no will install in: "/root/workspace/cmake/demo8" [Yn]: y Using target directory: /root/workspace/cmake/demo8/demo8-1.0.1-Linux Extracting, please wait... Unpacking finished successfully
After completion, you will be prompted to install demo8-1.0 In the 1-linux subdirectory, we can go in and execute the program:
[root@hackett demo8]# ls CMakeCache.txt cmake_install.cmake config.h CPackConfig.cmake CPackSourceConfig.cmake demo demo8-1.0.1-Linux.sh demo8-1.0.1-Linux.tar.Z main.cpp math CMakeFiles CMakeLists.txt config.h.in _CPack_Packages CTestTestfile.cmake demo8-1.0.1-Linux demo8-1.0.1-Linux.tar.gz install_manifest.txt Makefile [root@hackett demo8]# ./demo8-1.0.1-Linux/bin/demo 3 2 version : 1.0 Now we use our own Math library. 3 + 2 = 5
If you think the article is good, you can give a "three links", and the article is synchronized to the personal WeChat official account.
I'm hackett. I'll see you next time
Reference documents: