cmake简明教程-半小时从入门到精通

时间:2022-08-31 19:48:27

参考文献:

入门首先:http://www.hahack.com/codes/cmake/#

官方教程:https://cmake.org/cmake-tutorial/

官方教程译文:https://juejin.im/post/5a72775d6fb9a01cac187e96

简单操作语法:https://learnxinyminutes.com/docs/cmake/

官方cmake、ctest、cpack介绍:https://cmake.org/cmake/help/v3.11/

源码例程:https://gitee.com/qccz123456/learn_cmake,通过git log可查看具体每一步的步骤。


/*
step1:
    cmake -DUSE_MYSQRT=ON -DCMAKE_INSTALL_PREFIX=/home/eagle/Desktop/cmake_learn/build/output ..
step2:
    make
step3:
    make test
step4:
    make install
step5:
    cpack -C xxxx

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./build/output/lib
*/
/*
LearnCmake
  |__CMakeLists.txt
  |__LearnCmake_config.h.in
  |__main.cpp
  |__License.txt
  |__README
  |__feature
       |__CMakeLists.txt
       |__mysqrt.h
       |__mysqrt.cpp
*/ 
[LearnCmake/CMakeLists.txt]
/*       
cmake_minimum_required (VERSION 2.6)
project (LearnCmake)

# the version number, like define
set (LearnCmake_VERSION_MAJOR 1)
set (LearnCmake_VERSION_MINOR 0)
set (LearnCmake_VERSION_PATCH 0)

# Debug/Release settings
set (CMAKE_BUILD_TYPE "Debug")
set (CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set (CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

message (STATUS "src dir = ${PROJECT_SOURCE_DIR}")
message (STATUS "bin dir = ${PROJECT_BINARY_DIR}")
#message (WARNING "This is Warning")   # continue processing 
#message (SEND_ERROR "This is error")  # continue processing, but skip generation
#message (FATAL_ERROR "This is fatal") # stop processing and generation

# open make log
#set (CMAKE_VERBOSE_MAKEFILE ON)

# check system environment
include (CheckFunctionExists)
check_function_exists (pow HAVE_POW)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

# configure a header file to pass CMake settings to source code
# compile config.h.in to config.h
configure_file (
    "${PROJECT_SOURCE_DIR}/LearnCmake_config.h.in"
    "${PROJECT_BINARY_DIR}/LearnCmake_config.h"
)

# add the binary tree to the search path for include files
# so that we will find LearnCmake_config.h, like gcc -I
include_directories ("${PROJECT_BINARY_DIR}")

# set if USE_MYSQRT is defined in LearnCmake_config.h
# LearnCmake_config.h.in must use "#cmakedefine"
# ON/OFF value is related to cmake cache, is not initial value
# if define, must use "cmake -DUSE_MYSQRT=ON" 
option (USE_MYSQRT "use mysqrt library" ON)

if (USE_MYSQRT)
    # compile other source code files to libraries
    include_directories ("${PROJECT_SOURCE_DIR}/feature")
    add_subdirectory ("feature")
    set (EXTRA_LIBS ${EXTRA_LIBS} MySqrt)
endif (USE_MYSQRT)

# add the executable to run "./LearnCmake"
add_executable (LearnCmake main.cpp)
# add the executable, like gcc -L
target_link_libraries (LearnCmake ${EXTRA_LIBS})

# add install
install (TARGETS LearnCmake DESTINATION bin)
install (FILES ${PROJECT_BINARY_DIR}/LearnCmake_config.h DESTINATION include)

# add simple test
include (CTest)
add_test (LearnCmake LearnCmake)
add_test (LearnCmake2 LearnCmake)
set_tests_properties (LearnCmake2 PROPERTIES PASS_REGULAR_EXPRESSION "4")

# add macro test
macro (do_test arg result)
  add_test (test${arg} LearnCmake ${arg})
  set_tests_properties (test${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
# do a bunch of result based tests
do_test (0 "4")
do_test (2 "4")

# add cpack to pack binary/source code
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${LearnCmake_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${LearnCmake_VERSION_MINOR}")
set (CPACK_PACKAGE_VERSION_PATCH "${LearnCmake_VERSION_PATCH}")
include (CPack)
# pack binary package: cpack -C CPackConfig.cmake
# pack source package: cpack -C CPackSourceConfig.cmake
*/
[LearnCmake_config.h.in]
/*
//the configured options and settings for LearnCmake and direct copy
#define LearnCmake_VERSION_MAJOR @LearnCmake_VERSION_MAJOR@
#define LearnCmake_VERSION_MINOR @LearnCmake_VERSION_MINOR@

//cmake`s option to compile
#cmakedefine USE_MYSQRT
#cmakedefine HAVE_POW
*/
[main.cpp]

#include <iostream>
#include <math.h>
#include "LearnCmake_config.h"

#ifdef USE_MYSQRT
#include "mysqrt.h"
#endif

int main(void)
{
    std::cout << "learn cmake" << std::endl;
    std::cout << LearnCmake_VERSION_MAJOR << "." << LearnCmake_VERSION_MINOR << std::endl;
#ifdef USE_MYSQRT
    std::cout << mysqrt(2) << std::endl;
#endif
#ifdef HAVE_POW
    std::cout << pow(3, 2) << std::endl;
#endif

    return 0;
}
[LearnCmake/feature/CMakeLists.txt]
/*
#add_library (MySqrt mysqrt.cpp) # It is equal to the following :

# aux_source_directory find all src files of current directory 
aux_source_directory (. SRCS_LIB_DIR)
add_library (MySqrt SHARED ${SRCS_LIB_DIR})
add_library (MySqrt_static STATIC ${SRCS_LIB_DIR})

# add install : export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./build/output/lib
install (TARGETS MySqrt DESTINATION lib)
install (TARGETS MySqrt_static DESTINATION lib)
install (FILES mysqrt.h DESTINATION include)
*/
[mysqrt.h]

#ifndef __MYSQRT__
#define __MYSQRT__

int mysqrt(int num);

#endif


[mysqrt.cpp]

#include "mysqrt.h"

int mysqrt(int num)
{
    return num * num;
}