背景介绍
前面在介绍SQlite3 的使用时,用了CMake的方式,简单编译了源码,其中的CMakeLists.txt有如下内容
cmake_minimum_required ( VERSION 3.5 )
project( demo)
include_directories ( sqlite)
add_executable( main ${PROJECT_SOURCE_DIR} /src/main.c ${PROJECT_SOURCE_DIR} /sqlite/sqlite3.c)
target_link_libraries ( main pthread dl)
add_executable( sqliteShell ${PROJECT_SOURCE_DIR} /sqlite/shell.c ${PROJECT_SOURCE_DIR} /sqlite/sqlite3.c)
target_link_libraries ( sqliteShell pthread dl)
当执行cmake ../
命令的时候,就能够自动生成makefile,比较神奇。 在linux下一般过程就是
手动编写 CMakeLists.txt。 执行命令 cmake PATH 生成 Makefile ( PATH 是顶层CMakeLists.txt 所在的目录 )。 执行命令 make 进行编译。
CMake基本语法
基本语法格式:指令(参数 1 参数 2…)
参数使用括弧括起,参数之间使用空格或分号分开; 指令是大小写无关的,参数和变量是大小写相关的
CMake变量
CMake中所有变量都是string类型。可以使用set()和unset()命令来声明或者移除一个变量。 变量的引用:${变量名}
SET( var 666 )
MESSAGE( "var=${var} " )
常见CMake命令
常见的CMakeLists .txt都是由命令组成的,下面介绍一下主要的命令
最小版本
命令 cmake_minimum_required 含义 指定CMake的最小版本要求 格式 cmake_minimum_required(VERSION versionNumber [FATAL_ERROR]) 例子 cmake_minimum_required(VERSION 2.8.3)
设置变量
命令 SET 含义 指令用来定义变量的值,相当于编程语言中的赋值操作(VAR=VALUE) 格式 SET(VAR [VALUE]) 例子 # 定义SRC_LIST变量为三个cpp文件的列表。 SET(SRC_LIST main.cpp sqrt.cpp pow.cpp)
定义工程名称
命令 project 含义 定义工程名称,并可指定工程支持的语言 格式 project(projectname [CXX] [C] [Java])) 例子 project(HELLOWORLD))
头文件搜索
命令 include_directories 含义 向工程添加多个特定的头文件搜索路径 ,相当于指定g++编译器的-I参数 格式 include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …) 例子 include_directories(/usr/include/myincludefolder ./include))
库文件搜索
命令 link_directories 含义 向工程添加多个特定的库文件搜索路径 —>相当于指定g++编译器的-L参数 格式 link_directories(dir1 dir2 …) 例子 link_directories(/usr/lib/mylibfolder ./lib))
添加需要链接的共享库
命令 target_link_libraries 含义 为 target 添加需要链接的共享库 —>相同于指定g++编译器-l参数 格式 target_link_libraries(target library1 library2…) 例子 target_link_libraries(main hello)
添加编译参数
命令 add_compile_options 含义 添加编译参数 格式 add_compile_options() 例子 add_compile_options(-Wall -std=c99 -O2))
添加子文件夹
命令 iadd_subdirectory 含义 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制 存放的位置 格式 add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 例子 add_subdirectory(src)
获取源文件
命令 aux_source_directory 含义 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指 令临时被用来自动构建源文件列表 格式 aux_source_directory(dir VARIABLE) 例子 # 定义SRC变量,其值为当前目录下所有的源代码文件 aux_source_directory(. SRC) # 编译SRC变量所代表的源代码文件,生成main可执行文件 add_executable(main ${SRC})
生成库文件
命令 add_library 含义 生成库文件 格式 add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN) 例子 add_library(hello SHARED ${SRC})
生成可执行文件
命令 add_executable 含义 生成可执行文件 格式 add_executable(exename source1 source2 … sourceN) 例子 add_executable(main main.c)
安装
命令 install 含义 目标文件的安装 格式 INSTALL(TARGETS targets … [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION ] [PERMISSIONS permissions …] [CONFIGURATIONS [Debug|Release|…]] [COMPONENT ] [OPTIONAL] ][…]) 例子 INSTALL(TARGETS myrun mylib mystaticlib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION libstatic )
参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE 或者ADD_LIBRARY定义的目标文件,可能是可执行二进制、动态库、静态库。
目标类型:ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME特指可执行目标二进制。
DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来定义安装路径,就要写成相对路径 PATTERN用于使用正则表达式进行过滤,PERMISSIONS用于指定PATTERN过滤后的文件权限。
打印输出
命令 message 含义 相当于编程中的打印指令 格式 message([SEND_ERROR|STATUS|FATAL_ERROR] “Content”) SEND_ERROR 报错误信息,不终止CMake构建过程。 STATUS 普通输出信息。 FATAL_ERROR 报错误信息,终止CMake构建过程。 例子 message(STATUS “PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}”)
CMake常用变量
有些需要用set命令进行设置的。有些事直接使用。
编译选项
命令 含义 CMAKE_C_FLAGS gcc编译选项 CMAKE_CXX_FLAGS g++编译选项
例子
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
编译类型
命令 含义 CMAKE_BUILD_TYPE 编译类型(Debug, Release)
例子
set( CMAKE_BUILD_TYPE Debug)
set( CMAKE_BUILD_TYPE Release)
工程目录
命令 含义 CMAKE_BINARY_DIR 当就在工程顶层编译的时候,等同于工程顶层目录,如果是在build路径等顶层之外的地方编译时,就知道编译发生的路径。 PROJECT_BINARY_DIR 同上 _BINARY_DIR 同上 CMAKE_SOURCE_DIR 工程顶层目录 PROJECT_SOURCE_DIR 同上 _SOURCE_DIR 同上
其他参数
命令 含义 CMAKE_C_COMPILER 指定C编译器 CMAKE_CXX_COMPILER 指定C++编译器 EXECUTABLE_OUTPUT_PATH 可执行文件输出的存放路径 LIBRARY_OUTPUT_PATH 库文件输出的存放路径
例子
最后还是来一个简单的例子,就是之前编译Sqlite的例子
进入build路径 执行cmake ../
会生成Makefile 执行编译,就会生成我们需要的可执行程序 我们还可以稍微修改一下这个CMakeLists.txt,将sqlite3编译成库,然后将我们开发的文件与这个库编译到一起。
cmake_minimum_required ( VERSION 3.5 )
project( sqlitetest)
include_directories ( sqlite)
add_library( sqlite.a STATIC ${PROJECT_SOURCE_DIR} /sqlite/sqlite3.c)
add_executable( sqlitetest ${PROJECT_SOURCE_DIR} /src/main.c)
target_link_libraries ( sqlitetest sqlite.a pthread dl)
经过测试,没有问题
[ root@localhost build]
-- The C compiler identification is GNU 8.5 .0
-- The CXX compiler identification is GNU 8.5 .0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- PROJECT_BINARY_DIR: /home/sqlite3/build
-- PROJECT_SOURCE_DIR: /home/sqlite3
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sqlite3/build
[ root@localhost build]
[ 25 %] Building C object CMakeFiles/sqlite.a.dir/sqlite/sqlite3.c.o
[ 50 %] Linking C static library libsqlite.a.a
[ 50 %] Built target sqlite.a
[ 75 %] Building C object CMakeFiles/sqlitetest.dir/src/main.c.o
[ 100 %] Linking C executable sqlitetest
[ 100 %] Built target sqlitetest
[ root@localhost build]
CMakeCache.txt CMakeFiles cmake_install.cmake libsqlite.a.a Makefile sqlitetest
[ root@localhost build]
abc"abc" bytes: 16 , 10000 , 0
bytes: 16 , 10000 , 1
bytes: 16 , 10000 , 2
bytes: 16 , 10000 , 3
bytes: 16 , 10000 , 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
结束语
最近科兴也又被实名举报了,看来孩子的第三针要缓一下了,网上看好多人都因为疫苗出现了这样那样的反应,荨麻疹,白血病,各种结节,真是没有信心继续当小白鼠了。 不过最近身边的人好多都开始过敏性鼻炎了,已经不是少数了,每年春天,会因为一批树木的花粉,杨柳絮,很多人过敏,每年秋天,会因为一大批蒿,苋类植物的花粉,还有一批人过敏, 有人难受一个季度,也有人难受半年。