菜鸟笔记
提升您的技术认知

CMakeList使用总结

一、cmake功能介绍

cmake是跨平台编译工具,编写简单好维护,是make的高级用法。
1.编写CMakeList.txt文件,通过cmake生成Makefile文件,make生成可执行文件、静态库、共享库。
2.cmake是一个跨平台的编译工具,可以用简单的语句来描述所有平台编译。make工具依赖于平台,GNU make,Qt qmake,MS nmake,BSD pmake,makepp等等,这些不同make工具遵循不同的规范标准,所有执行的Makefile文件格式格式不同。
在线帮助文档:https://cmake.org/documentation
3. cmake比configure优秀
configure也是跨平台编译工具,使用比较繁琐.configure脚本为了让一个程序能够在各种不同类型的机器上运行而设计的。在使用make编译源代码之前,configure会根据自己所依赖的库而在目标机器上进行匹配。约定俗成的,所有的configure脚本都把脚本文件名起为configure,一般来讲都是shell脚本,根据所在的系统环境生成makefile文件。有时候看到一些程序的configure内容超级之多,让人难以看下去。configure脚本运行时扫描当前环境,生成一个名为config.status的子脚本。子脚本将Makefile.in文件转换为适应于当前系统环境的Makefile文件。
GNU build system这个工具能够帮助我们生成configure脚本,又叫做Autotools。Autotools包含的命令有autoconf,automake,libtool。

二、CMakeLists编写介绍

1.指定运行配置cmake最低版本: cmake_minimum_required(VERSION 3.13)
2.设置工程名称: project(Test) 获取${PROJECT_NAME}
3.设置变量: SET(VAR 1) ${变量名}
4.获取系统环境变量:

$ENV{
  系统变量} $ENV{
  PATH}

5.指定可执行文件生成路径:

SET(EXECUTABLE_OUTPUT_PATH "xxx/bin")

6.指定输出动态库的目录位置:

SET(LIBRARY_OUTPUT_PATH "xxx/lib")

7.获取源代码、头文件路径:

FILE(GLOB SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
FILE(GLOB HEAD_LIST "${PROJECT_SOURCE_DIR}/include/*.h")

8.添加头文件路径:

include_directories("${PROJECT_SOURCE_DIR}/include")

9.添加链接库路径:

link_directories("${PROJECT_SOURCE_DIR}/lib")

10.添加生成可执行文件:

add_executable(${PROJECT_NAME} ${SRC_LIST} ${HEAD_LIST})

11.链接库名:

target_link_libraries(${PROJECT_NAME} ${LIB_NAME})

12.添加生成动态库或静态库: 不写默认静态库

add_library(${LIB_NAME} SHARED ${PROJECT_SOURCE_DIR}/third/test.cpp)
add_library(${LIB_NAME}_static STATIC ${PROJECT_SOURCE_DIR}/third/test.cpp)

13.静态库的输出名称:

set_target_properties(${LIB_NAME}_static PROPERTIES OUTPUT_NAME ${LIB_NAME})

14.设置预处理宏开关 开启:

option(USE_TEST "option for test" ON)

15.配置一个头文件用于传递一些CMake中的配置到源代码中

configure_file("${PROJECT_SOURCE_DIR}/config.in" "${PROJECT_SOURCE_DIR}/config.h")

16.make install 
16.1安装可执行文件、静态库、动态库。

  install(TARGETS myrun mylib mystaticlib
	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} )

16.2安装整个目录

  install(DIRECTORY ${OUT_PATH} DESTINATION ${PROJECT_SOURCE_DIR})
  install(DIRECTORY ${OUT_PATH} DESTINATION ${PROJECT_SOURCE_DIR}
	 PATTERN "${EXE_NAME}" PERMISSIONS
 	OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)

16.3安装文件

  install(FILES "${PROJECT_BINARY_DIR}/bin/${EXE_NAME}" DESTINATION "${PROJECT_SOURCE_DIR}/bin" PATTERN "${EXE_NAME}" PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
  install(FILES "${PROJECT_BINARY_DIR}/lib/lib${LIB_NAME}.a" DESTINATION "${PROJECT_SOURCE_DIR}/lib")
  install(FILES "${PROJECT_BINARY_DIR}/lib/lib${LIB_NAME}.so" DESTINATION "${PROJECT_SOURCE_DIR}/lib")

三、CMakeList构建Qt工程

1.设置开启MOC UIC RCC编译器

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

2.添加qt模块 添加头文件路径 依赖库路径 库名称 findxxx.cmake xxxConfig.cmake

find_package(Qt5Widgets CONFIG REQUIRED)
target_link_libraries(${
  PROJECT_NAME}  Qt5::Widgets)
<NAME>_FOUND   <NAME>_INCLUDE_DIRS   or    <NAME>_INCLUDES
<NAME>_LIBRARIE   or     <NAME>_LIBRARIES   or   <NAME>_LIBS
<NAME>_DEFINITIONS
===================================
find_package(PkgConfig)
pkg_search_module(Qt5Widgets REQUIRED Qt5Widgets)
target_link_libraries(${
  PROJECT_NAME} ${
  Qt5Widgets_LIBRARIES})
=====================================================
(pkg-config xxx a.默认usr/bin/*.pc  b.读取环境变量PKG_CONFIG_PATH  c.pkg-config --variable pc_path pkg-config )
(动态库 a.LD_LIBRARY_PATH b./etc/ld.so.conf c./lib  or /usr/lib)

四、CMakeList添加第三方库

1.编写编译安装脚本 命名为uchartdet_install.sh

cd libiconv-1.16
path=”`pwd`/../lib” #生成路径自己指定
./configure --enable-extra-encodings --prefix=$path --enable-static --disable-shared
make
make install

2.在第三方库third目录下编写CMakeList.txt

execute_process(COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/uchartdet_install.sh" WORKING_DIRECTORY ${
  CMAKE_CURRENT_SOURCE_DIR})

3.在上级CMakeList.txt添加add_subdirectory(third)

相关demo文档下载:https://download.csdn.net/download/wml00876/19671522

简单demo

#最低cmake版本
cmake_minimum_required(VERSION 3.0)                                                                               
#项目名
project(aqp)                                                                                                      
#引入文件
file(GLOB HEADS "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")                                                              
file(GLOB SRCS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.qrc")                           
                                                                                                              
 #添加Qt模块                                                                                                       
find_package(Qt5Core REQUIRED)                                                                                    
find_package(Qt5Widgets REQUIRED)                                                                                 
                                                                                                                      
#创建可执行文件                                                                                                   
add_executable(aqp                                                                                                
            ${
  HEADS}                                                                                                  
			${
  SRCS}                                                                                                       
		)                                                                                                             
#引用路径,包含编译给定目标时需要使用的目录                                                                                                                 
target_include_directories(${
  PROJECT_NAME} PUBLIC                                                                 
${
  Qt5Core_INCLUDE_DIRS}                                                                                       
${
  Qt5Widgets_INCLUDE_DIRS}                                                                                    
)