cmake基础介绍(一)
CMake是一个跨平台的编译工具(cross platform make)。
CMakeLists.txt 简单介绍如下:
# Auto CMakeLists.txt: frame with cppunit use for lintcode/leetcode
# minimum cmake version
cmake_minimum_required(VERSION 3.7) # cmake最低版本号要求
PROJECT(demo) # 项目名
SET(mname demo ) # 将demo 赋值给变量mname
SET( cppunit_test cppunit_demo_test )
SET( ROOTPATH ${CMAKE_SOURCE_DIR})
# defining common source variables
aux_source_directory(main SRC ) # 查找main 目录下的所有源文件 将文件名保存到SRC
aux_source_directory(test_cppunit TESTSRC ) # test_cppunit目录下的所有源文件 将文件名保存到TESTSRC
# add_subdirectory(sub):包含子目录 sub。在编译时先编译子目录下的CMakeLists.txt和源码;
MESSAGE(STATUS "project name: " ${PROJECT_NAME})
SET(LIBRARY_OUTPUT_PATH ${ROOTPATH}/lib) # 设置生成库输出目录
SET(EXECUTABLE_OUTPUT_PATH ${ROOTPATH}/bin) # 设置可执行文件输出目录(target)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${ROOTPATH}/bin/Debug )
MESSAGE(STATUS "library_output_path : " ${LIBRARY_OUTPUT_PATH} )
MESSAGE(STATUS "executable_output_path: " ${EXECUTABLE_OUTPUT_PATH} )
MESSAGE(STATUS "cmake_runtime_output_directory_debug: " ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG} )
add_definitions(-DTYPEDEBUG) #添加宏定义 TYPEDEBUG
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
MESSAGE(">>>> cppbuilder init start:")
if(SRC)
add_definitions("-g -Wall -std=c++11")
include_directories(include) #包含目录,指定头文件的搜索路径;
add_executable( t_${mname} ${SRC} ) #生成可执行文件
ADD_LIBRARY( ${mname} STATIC ${SRC}) #生成静态库 将STATIC替换为SHARED生成动态库
#target_link_libraries( ${mname} childlib ) # 添加链接库
SET(LIBRARY_OUTPUT_PATH ${ROOTPATH}/lib)
#ADD_LIBRARY( ${mname} SHARED ${SRC})
MESSAGE("project src file show: ")
foreach(_var ${SRC})
MESSAGE(" ${_var}")
endforeach()
MESSAGE(" ")
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${ROOTPATH}/bin/Debug )
endif(SRC)
MESSAGE(">>>> cppbuilder init end <<<<")
1.1 基础语法介绍
1 设置变量
### 字符串
set(mystring "hello wold " "xiaojiejie ")
string(APPEND mystring "xiaogege ")
message("======: " ${mystring} )
### 列表
set(mylist "c " "c++ " "java " "python ")
set(mylist ${mylist} "lua ")
list(APPEND mylist "php " "javascript ")
message("======: " ${mylist} )
cmake变量定义的方式有两种:隐式定义和显式定义。
- 1 隐式定义 前面举了一个隐式定义的例子,就是PROJECT指令,他会隐式的定义BINARY_DIR和SOURCE_DIR两个变量。
- 2 显示定义 显式定义的例子我们前面也提到了,使用 SET 指令,就可以构建一个自定义变量了。${valuename} 来引用该变量
CMake常用变量
变量名 | 变量说明 |
---|---|
PROJECT_NAME | 返回通过PROJECT指令定义的项目名称 |
PROJECT_SOURCE_DIR | CMake源码地址,即cmake命令后指定的地址 |
PROJECT_BINARY_DIR | 运行cmake命令的目录,通常是PROJECT_SOURCE_DIR下的build目录 |
CMAKE_MODULE_PATH | 定义自己的cmake模块所在的路径 |
CMAKE_CURRENT_SOURCE_DIR | 当前处理的CMakeLists.txt所在的路径 |
CMAKE_CURRENT_LIST_DIR | 当前文件夹路径 |
CMAKE_CURRENT_LIST_FILE | 输出调用这个变量的CMakeLists.txt的完整路径 |
CMAKE_CURRENT_LIST_LINE | 输出这个变量所在的行 |
CMAKE_RUNTIME_OUTPUT_DIRECTORY | 生成可执行文件路径 |
CMAKE_LIBRARY_OUTPUT_DIRECTORY | 生成库的文件夹路径 |
CMAKE_BUILD_TYPE | 指定基于make的产生器的构建类型(Release,Debug) |
CMAKE_C_FLAGS | *.C文件编译选项,如 -std=c99 -O3 -march=native |
CMAKE_CXX_FLAGS | *.CPP文件编译选项,如 -std=c++11 -O3 -march=native |
CMAKE_CURRENT_BINARY_DIR | target编译目录 |
CMAKE_INCLUDE_PATH | 环境变量,非cmake变量 |
CMAKE_LIBRARY_PATH | 环境变量 |
CMAKE_STATIC_LIBRARY_PREFIX | 静态库前缀, Linux下默认为lib |
CMAKE_STATIC_LIBRARY_SUFFIX | 静态库后缀,Linux下默认为.a |
CMAKE_SHARED_LIBRARY_PREFIX | 动态库前缀,Linux下默认为lib |
CMAKE_SHARED_LIBRARY_SUFFIX | 动态库后缀,Linux下默认为.so |
BUILD_SHARED_LIBS | 如果为ON,则add_library默认创建共享库 |
CMAKE_INSTALL_PREFIX | 配置安装路径,默认为/usr/local |
CMAKE_ABSOLUTE_DESTINATION_FILES | 安装文件列表时使用ABSOLUTE DESTINATION 路径 |
CMAKE_AUTOMOC_RELAXED_MODE | 在严格和宽松的automoc模式间切换 |
CMAKE_BACKWARDS_COMPATIBILITY | 构建工程所需要的CMake版本 |
CMAKE_COLOR_MAKEFILE | 开启时,使用Makefile产生器会产生彩色输出 |
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS | 用来控制IF ELSE语句的书写方式 |
系统变量
- CMAKE_MAJOR_VERSION , CMAKE 主版本号,比如 2.4.6 中的 2
- CMAKE_MINOR_VERSION , CMAKE 次版本号,比如 2.4.6 中的 4
- CMAKE_PATCH_VERSION , CMAKE 补丁等级,比如 2.4.6 中的 6
- CMAKE_SYSTEM ,系统名称,比如 Linux-2.6.22
- CMAKE_SYSTEM_NAME ,不包含版本的系统名,比如 Linux
- CMAKE_SYSTEM_VERSION ,系统版本,比如 2.6.22
- CMAKE_SYSTEM_PROCESSOR ,处理器名称,比如 i686.
- UNIX ,在所有的类 UNIX 平台为 TRUE ,包括 OS X 和 cygwin
- WIN32 ,在所有的 win32 平台为 TRUE ,包括 cygwin
2 流程控制
set(VAR1 "world")
if(VAR1 MATCHES "Hello")
message("this is hello")
message("this is hello2")
elseif(VAR1 MATCHES "world")
message("this is world")
message("this is world2")
else()
message(" un expect value")
endif()
foreach(_value ${mylist})
message(" " ${_value} )
endforeach(_value ${})
# foreach(loop_var RANGE start stop [step]) 的用法。 在foreach循环中,支持break()和continue()。
set(result 0)
foreach(_var RANGE 0 100)
math(EXPR result "${result}+${_var}")
endforeach()
message("from 0 plus to 100 is:${result}")
#用于比较数字的大小LESS:小于GREATER:大于EQUAL:等于GREATER_EQUAL:大于等于LESS_EQUAL:小于等于
#用于比较字符串LESS:小于STRGREATER:大于STREQUAL:等于STRLESS_EQUAL:小于等于STRGREATER_EQUAL:大于等于
set(i 5 )
while( i GREATER 0 )
message("i " ${i})
math(EXPR i "${i} -1 ")
endwhile()
3 macro和function
function( [arg1 [arg2 [arg3 …]]]) COMMAND1(ARGS …) COMMAND2(ARGS …) … endfunction()
定义一个函数名为,参数名为arg1 arg2 arg3(…)。 函数体内的命令直到函数被调用的时候才会去执行。
变量 | 说明 |
---|---|
ARGV# | #是一个下标,0指向第一个参数,累加 |
ARGV | 所有的定义时要求传入的参数 |
ARGN | 定义时要求传入的参数以外的参数,比如定义宏(函数)时,要求输入1个,书记输入了3个,则剩下的两个会以数组形式存储在ARGN中 |
ARGC | 传入的实际参数的个数,也就是调用函数是传入的参数个数 |
macro(FOO arg1 arg2 arg3)
message(STATUS "this is arg1:${arg1},ARGV0=${ARGV0}")
message(STATUS "this is arg2:${arg2},ARGV1=${ARGV1}")
message(STATUS "this is arg3:${arg3},ARGV2=${ARGV2}")
message(STATUS "this is argc:${ARGC}")
message(STATUS "this is args:${ARGV},ARGN=${ARGN}")
endmacro(FOO)
function(FUNCTION_TEST arg1)
message("\n")
message(STATUS "this is arg1:${arg1} ARGV0=${ARGV0}")
message(STATUS "this is argn:${ARGN}")
message(STATUS "this is ARGC:${ARGC}")
message("\n")
endfunction(BAR arg1)
set(p1 one)
set(p2 two)
set(p3 three)
set(p4 four)
set(p5 five)
set(p6 first)
set(p7 second)
FOO(${p1} ${p2} ${p3} ${p4} ${p5})
FUNCTION_TEST(${p6} ${p7} ${p1} )
最重要的教程还是官方文档, 用cmake --help-command 命令 可以查看用法,效果类似如下: