高密哪里有做网站的,电商网站建设题库,广州公司建设网站,免费微信小程序免费制作平台文章目录 前言一、快速开始编译C/C代码1. 只有源码的项目2. 包含库的项目3. 编译成库给他人使用使用cmake的流程1. 生成构建系统2. 执行构建3. 执行测试4. 安装 打包 二、cmake 语法简介1 变量2 条件语句3 脚本命令**消息打印****if-else**:**list命令**#xff1a… 文章目录 前言一、快速开始编译C/C代码1. 只有源码的项目2. 包含库的项目3. 编译成库给他人使用使用cmake的流程1. 生成构建系统2. 执行构建3. 执行测试4. 安装 打包 二、cmake 语法简介1 变量2 条件语句3 脚本命令**消息打印****if-else**:**list命令****文件操作****配置文件生成**执行系统命令查找库文件include其他模块 三、配置案例四、配置说明配置项目指定编译器语言版本配置编译选项debug or release 附录内建变量 reference 前言
CMakeake是什么是用来做什么的以及如何 cmake是一个用于管理和构建源代码的工具。 cmake广泛应用于编译C/C代码其实也可以用于编译其他语言。 cmake可实现跨平台构建、编译c/c源码。 cmake除了用于编译外还提供了ctest, cpack用于测试安装或打包。 第一章适用于新手在不了解cmake语言的情况下可快速构建自己的项目
一、快速开始编译C/C代码
1. 只有源码的项目
.
├── include
│ ├── hea2.h
│ └── head1.h
├── main.c
└── src├── fun1.c└── fun2.c在根目录下新建CMakeLists.txt文件
# 新项目必须的
cmake_minimum_required(VERSION 3.10)
# 新项目必须的
project(tutorial VERSION 1.0)
# 生成可执行文件必须的
add_executable(mainmain.csrc/fun1.csrc/fun2.c
)
# 指定头文件搜索路径
target_include_directories(main PUBLIC./include
)接下来在根目录下新建build目录然后运行cmake命令
mkdir build cd build
cmake .. # 生成构建系统
cmake --build . #执行构建2. 包含库的项目
和1的区别仅为在CMakeLists.txt中把依赖添加进去
target_link_libraries(mainlibname1libname2
)
target_link_directories(main PUBLIC./lib
)然后执行cmake 命令即可
3. 编译成库给他人使用
若需要将源文件编译成库而不是可执行文件则仅需修改CMakeLists.txt文件即可 生成静态库
add_library(main STATIC # STATIC可写可不写main.csrc/fun1.csrc/fun2.c
)生成动态库
cmake_minimum_required(VERSION 3.10)project(tutorial VERSION 1.0)add_library(main SHAREDmain.csrc/fun1.csrc/fun2.c
)
target_include_directories(main PUBLIC./include
)使用cmake的流程
生成构建系统buildsystem比如make工具对应的Makefile文件执行构建比如make声明目标文件执行测试、安装或打包
1. 生成构建系统
通过cmake 命令生成构建系统
参数含义-S指定源文件根目录必须包含一个CMakeLists.txt文件-B指定构建目录构建生成的中间文件和目标文件的生成路径-D指定变量格式为-D -D后面的空格可以省略
指定当前目录为源文件目录其中包含CMakeLists.txt文件使用build目录作为构建目录 cmake -S . -B build -DCMAKE_BUILD_TYPEDebug -DAUTHORme 使用-D设置的变量在CMakeLists.txt中生效可以设置cmake的内置支持的一些变量控制构建的行为当然也可以使用自定义的变量在CMakeLists.txt中自行判断做不同的处理。 2. 执行构建
cmake --build . –buid 后面跟构建系统所在目录
3. 执行测试
如果在CMakeLists.txt中添加如下包含测试的功能则在执行构建后可进行测试
enable_testing()
# include(CTest) # 添加CTest模块, 可代替enable_testing
add_test(NAME normal_test COMMAND main )
set_tests_properties(normal_test PROPERTIES PASS_REGULAR_EXPRESSION yes) # main程序输出“yes”视为通过4. 安装 打包
在CMakeLists.txt中添加如下内容
install(TARGETS binary_nam DESTINATION ./install/bin)
install(FILES include/head.h DESTINATION ./install/inc)
install(EXPORT Json FILE FILE Json.cmake DESTINATION ./install/lib)然后执行
cmake --install .
或者
cmake --install . --prefix ~/myuser/installdir打包部分测试未通过
二、cmake 语法简介
1 变量
CMake中使用set和unset命令设置或者取消设置变量
一般变量 设置的变量可以是字符串数字或者列表直接设置多个值或者使用分号隔开的字符串格式为val1;val2;val3
# set var
set(val1 a)
set(val2 hello world)
# set list
set(list1 a b) # saved as a;b
set(list2 a;b)
set(list3 a;b)set(num 90) # saved as string, but can compare with other number string
set(falg ON) # bool value如果要设置的变量值包含空格则需要使用双引号或者使用转义否则可以省略双引号如果设置多个值或者字符串值的中间有;“则保存成list同样是以”;分割的字符串变量可以被list命令操作单个值的变量相当于只有一个元素的列表引用变量${variable}在if()条件判断中可以简化为只用变量名variable。 Cache变量 Cache变量缓存条目cache entries的作用主要是为了提供用户配置选项如果用户没有指定则使用默认值设置方法如下
# set(variable value... CACHE type docstring [FORCE])
set(CACHE_VAR Default cache value CACHE STRING A sample for cache variable)主要为了提供可配置变量比如编译开关引用CACHE变量$CACHE{}Cache变量会被保存在构建目录下的CMakeCache.txt中缓存起来之后是不变的除非重新配置更新 环境变量
修改当前处理进程的环境变量设置和引用格式为
# set(ENV{variable} [value])
set(ENV{ENV_VAR} $ENV{PATH})
message(Value of ENV_VAR: $ENV{ENV_VAR})和CACHE变量类似要引用环境变量格式为$ENV{}。
2 条件语句
字符串比较比如STREQUAL、STRLESS、STRGREATER等数值比较比如EQUAL、LESS、GREATER等布尔运算AND、OR、NOT路径判断比如EXISTS、IS_DIRECTORY、IS_ABSOLUTE等版本号判断使用小括号可以组合多个条件语句比如(cond1) AND (cond2 OR (cond3))
常量
ON、YES、TRUE、Y和非0值均被视为True0、OFF、NO、FALSE、N、IGNORE、空字符串、NOTFOUND、及以-NOTFOUND结尾的字符串均视为False
对于变量只要其值不是常量中为False的情形则均视为True。
3 脚本命令
消息打印
message([mode] message text...)mode:
空或者NOTICE比较重要的信息如前面演示中的格式DEBUG调试信息主要针对开发者STATUS项目使用者可能比较关心的信息比如提示当前使用的编译器WARNINGCMake警告不会打断进程SEND_ERRORCMake错误会继续执行但是会跳过生成构建系统FATAL_ERRORCMake致命错误会终止进程
if-else:
set(emp_str )
if (NOT emp_str AND flag and num less 50 and not not_define_var)message(STATUS first )
elseif (emp_str)message(STATUS second)
else()message(third)
endif()此外还有 for/while等
list命令
APPEND往列表中添加元素LENGTH获取列表元素个数JOIN将列表元素用指定的分隔符连接起来
list(APPEND var val)文件操作
CMake的file命令支持的操作比较多可以读写、创建或复制文件和目录、计算文件hash、下载文件、压缩文件等等。
file(GLOB_RECURSE ALL_SRCsrc/module1/*.csrc/module2/*.c)GLOB_RECURSE表示执行递归查找查找目录下所有符合指定正则表达式的文件。 配置文件生成
使用configure_file命令可以将配置文件模板中的特定内容替换生成目标文件。 输入文件中的内容VAR或者${VAR}在输出文件中将被对应的变量值替换。 使用方式为
PROJECT(tutorial VERSION 1.0.1.1)
configure_file(version.h.in ${PROJECT_BINARY_DIR}/version.h)version.h.in
#define VERSION VERSION
#define MAJOR tutorial_VERSION_MAJOR
#define MINOR tutorial_VERSION_MINOR
#define PATCH tutorial_VERSION_PATCH执行系统命令
使用execute_process命令可以执行一条或者顺序执行多条系统命令对于需要使用系统命令获取一些变量值是有用的。比如获取当前仓库最新提交的commit的commit id
execute_process(COMMAND bash -c git rev-parse --short HEAD OUTPUT_VARIABLE COMMIT_ID)查找库文件
通过find_library在指定的路径和相关默认路径下查找指定名字的库常用的格式如下
find_library (VAR name1 [path1 path2 ...])找到的库就可以被其他target使用表明依赖关系。
include其他模块
include命令将cmake文件或者模块加载并执行
include(CPack) # 开启打包功能
include(CTest) # 开启测试相关功能CMake自带有很多有用的模块可以看看官网的链接cmake-modules对支持的功能稍微有所了解后续有需要再细看文档。当然如果感兴趣也可以直接看CMake安装路径下的目录CMake\share\cmake-\Modules中的模块源文件。
关于CMake脚本源文件的示例位于路径cmake/script_demo.cmake可以使用cmake -P cmake/script_demo.cmake执行查看结果; 关于配置文件生成的操作在项目根目录的CMakeLists.txt中也有示例。
三、配置案例
main CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(tutorial VERSION 2.3)
set(binary_name haha)
add_executable(${binary_name}main.cpp)
message(project_source_dir: ${PROJECT_SOURCE_DIR}, binary: ${PROJECT_BINARY_DIR})
configure_file(tutorialconfig.h.in tutorialconfig.h) # comm cmake and src
######################### change c standard ################################
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_17)
target_link_libraries(${binary_name} PUBLIC tutorial_compiler_flags)
#-------------------------------------------------------------------------------
add_subdirectory(libs/json) # subproj CMakeLists.txt
target_link_libraries(${binary_name} PUBLIC Json)
target_include_directories(${binary_name} PUBLIC ${PROJECT_BINARY_DIR}${PROJECT_SOURCE_DIR}${PROJECT_SOURCE_DIR}/libs/json${PROJECT_SOURCE_DIR}/libs/math)
target_link_options(${binary_name} PUBLIC -D_BUG_)
# cmake . -DUSE_MYLIBOFF
option(USE_MYLIB Use providesd imt XXX ON)
if (USE_MYLIB)target_compile_definitions(${binary_name} PRIVATE USE_MYLIB)message(oo USE_MYLIB macro used)
else()message(oo USE_MYLIB macro not used)
endif()
######################### Generator Expression ###############################
set(gcc_like_cxx $COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC)
set(msvc_cxx $COMPILE_LANG_AND_ID:CXX,MSVC)
target_compile_options(tutorial_compiler_flags INTERFACE# $${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat2;-Wunused# $${msvc_cxx}:-W3# 仅在构建时启用在作为项目的模块时不启用$${gcc_like_cxx}:$BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat2;-Wunused$${msvc_cxx}:$BUILD_INTERFACE:-W3
)
########################### install ctest ############################
# cmake --install .
# cmake --install . --prefix /home/myuser/installdir
install(TARGETS ${binary_name} DESTINATION ${PROJECT_SOURCE_DIR}/install/bin)
install(FILES ${PROJECT_BINARY_DIR}/tutorialconfig.h DESTINATION ${PROJECT_SOURCE_DIR}/install/include)
# install(EXPORT Json FILE Json.cmake DESTINATION ${PROJECT_SOURCE_DIR}/install/lib)
enable_testing() # enable testing
add_test(NAME Runs COMMAND ${binary_name} 25)
add_test(NAME Usage COMMAND ${binary_name} 4)
set_tests_properties(Usage PROPERTIES PASS_REGULAR_EXPRESSION Usage:.*number)
add_test(NAME StandardUse COMMAND ${binary_name} 4)
set_tests_properties(StandardUse PROPERTIES PASS_REGULAR_EXPRESSION 4 is 2)
function(do_test target arg result)add_test(NAME Comp${arg} COMMAND ${target} ${arg})set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endfunction()
do_test(${binary_name} 4 4 is 2)
do_test(${binary_name} 5 5 is 2)
do_test(${binary_name} 6 6 is 2)
do_test(${binary_name} 7 7 is 2)
do_test(${binary_name} 8 8 is 2)
do_test(${binary_name} 9 9 is 2)
############################# Dashboard ######################
include(CTest) # include CTest module
if(UNIX)message(hello------------)
endif()
########################## system introspection ##############################
include(CheckCXXSourceCompiles) # include this module, check_XXX_compiles
check_cxx_source_compiles(#include cmathint main() {std::log(1.0);return 0;}HAVE_LOG
)
check_cxx_source_compiles(#include cmathint main() {std::exp(1.0);return 0;}HAVE_EXP
)
if (HAVE_LOG AND HAVE_EXP)target_compile_definitions(${binary_name} PRIVATE HAVE_LOG HAVE_EXP)message(support exp and log function)
else()message(not support exp or log function)
endif()
######################### packaging installer ? failed #############################
# This module will include any runtime libraries that are needed by the project for the current platform
include(InstallRequiredSystemLibraries)
# set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/License.txt)
set(CPACK_PACKAGE_VERSION_MAJOR ${tutorial_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${tutorial_VERSION_MINOR})
set(CPACK_SOURCE_GENERATOR TGZ)
include(CPack)
# then cpack / cpack -G ZIP -C Debug -G:generator,-C:multi-config specify configurationsub CMakeLists.txt
include(MakeTable.cmake) # include and execute
# cmake_minimum_required(VERSION 3.0)
# project(cppjsonrw VERSION 1.9)
add_library(Json json_reader.cc json_value.cc json_writer.cc ${CMAKE_CURRENT_BINARY_DIR}/table.h)
target_include_directories(JsonINTERFACE # consumers require but the producer doesnt# if not exprot${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}# else export# $BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}# $INSTALL_INTERFACE:include
)
target_link_libraries(Json PUBLIC tutorial_compiler_flags)
message(Jproject source dir: ${PROJECT_SOURCE_DIR})
message(Jcmake source dir: ${CMAKE_SOURCE_DIR})
message(Jcmake current source dir: ${CMAKE_CURRENT_SOURCE_DIR})
####################### static or dynamic lib ################################
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
option(BUILD_SHARED_LIBS Build using shared libraries ON)
########################### install ############################
set(installable_libs tutorial_compiler_flags Json)
# if (TARGET Json)
# list(APPEND installable_libs Json)
# endif()
install(TARGETS ${installable_libs} EXPORT Json DESTINATION ${PROJECT_SOURCE_DIR}/install/lib)
install(FILES json.h DESTINATION ${PROJECT_SOURCE_DIR}/install/include)
####################### custom command and generated file ####################四、配置说明
配置项目
# 配置项目
project(tutorial VERSION 1.0.1 LANGUAGES C CXX)指定编译器语言版本
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 17)配置编译选项
通过命令add_compile_options可为所有编译器配置选项同时对多个编译器生效通过设置变量CMAKE_C_FLAGS可以配置C编译器选项设置变量CMAKE_CXX_FLAGS可配置C编译器的编译选项。
add_compile_options(-Wall -g)
// add_compile_options(-g;-Wall)
set(CMAKE)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -pipe -stdc99)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -pipe -stdc17)debug or release
cmake --build . -DCMAKE_BUILD_TYPEDebugset(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} -g -O0)
set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} -g -O0)set(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} -O2)
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} -O2)附录
内建变量
名PROJECT_SOURCE_DIR最近的CMakeLists.txt中含project命令所在目录PROJECT_BINARY_DIR最近的含有project的对应构建树中所在目录CMAKE_SOURCE_DIR顶层CMakeLists.txt所在目录CMAKE_BINARY_DIR对应构建树顶层目录CMAKE_CURRENT_SOURCE_DIR当前CMakeLists.txt所在目录CMAKE_CURRENT_BINARY_DIR对应构建树当前所在目录PROJECT-NAME_VERSION_MAJOR
reference https://cmake.org/cmake/help/latest/ cmake-commands cmake-modules(7)-https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html