learn cmake
cmake简介
在cmake出现之前,在linuxiax下,大型软件系统一般使用make来控制编译过程,而在Windows下可能是用vs下一个project来构建。一个复杂的系统本身依赖关系就很麻烦,如果想把一个linux下的项目拿到Windows下编译,我们可能要重新建立vs工程,这将是一项乏味且令人讨厌的工作。
cmake就是为了解决这个问题而生,同时他也使得控制软件编译过程变得更简单。其基本原理就是开发人员使用cmake的语法规则编写CMakeLists.txt,cmake executable根据该文件在linux下生产Makefile,在Windows下可能生成vs工程。然后再通过make命令编译、安装。开发人员不再需要自己去写Makefile了。
cmake语法
cmake的语法应该不算难,在初学者看来,至少比make要更user friendly一些。具体的语法可以参见cmake document。下面贴出开源项目muduo的root directory下的CMakeLists.txt,我在该文件中加入了一些comment,可以对cmake command有初步的映像。
# for cmake version control, if cmake version lower than this,
# cmake failed. Also this will call cmake_policy(VERSION, 2.6)
# for bug control.
# I see most of projects set this to 2.6
cmake_minimum_required(VERSION 2.6)
#project(<PROJECT-NAME> [LANGUAGES] [<language-name>...])
#default C CXX
#this must call (explict or implict)
project(muduo C CXX)
#enable ctest
#will need add_test() command, may in subdirectory/CMakeList.txt
enable_testing()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
#Signatures of this command that specify a <value>... placeholder expect zero or more arguments. Multiple arguments will be joined as a ;-list to form the actual variable value to be set. Zero arguments will cause normal variables to be unset. See the unset() command to unset variables explicitly.
set(CXX_FLAGS
-g
# -DVALGRIND
# -DMUDUO_STD_STRING
-DCHECK_PTHREAD_RETURN_VALUE
-D_FILE_OFFSET_BITS=64
-Wall
-Wextra
#-Werror
-Wconversion
-Wno-unused-parameter
-Wold-style-cast
-Woverloaded-virtual
-Wpointer-arith
-Wshadow
-Wwrite-strings
-march=native
# -MMD
# -std=c++0x
-rdynamic
)
#list(LENGTH <list> <output variable>)
#list(GET <list> <element index> [<element index> ...]
# <output variable>)
#list(APPEND <list> [<element> ...])
#list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)
#list(FIND <list> <value> <output variable>)
#list(INSERT <list> <element_index> <element> [<element> ...])
#list(REMOVE_ITEM <list> <value> [<value> ...])
#list(REMOVE_AT <list> <index> [<index> ...])
#list(REMOVE_DUPLICATES <list>)
#list(REVERSE <list>)
#list(SORT <list>)
if(CMAKE_BUILD_BITS EQUAL 32)
list(APPEND CXX_FLAGS "-m32")
endif()
#replace all ";" in CXX_FLAGS with " " and output to CMAKE_CXX_FLAGS
string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -finline-limit=1000 -DNDEBUG")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
# call /usr/share/cmake-3.5/Modules/FindBoost.cmake
find_package(Boost REQUIRED)
find_package(Protobuf)
find_package(CURL)
find_package(ZLIB)
# find the path where ares.h in
find_path(CARES_INCLUDE_DIR ares.h)
find_library(CARES_LIBRARY NAMES cares)
find_path(MHD_INCLUDE_DIR microhttpd.h)
find_library(MHD_LIBRARY NAMES microhttpd)
find_library(BOOSTTEST_LIBRARY NAMES boost_unit_test_framework)
find_library(BOOSTPO_LIBRARY NAMES boost_program_options)
find_path(TCMALLOC_INCLUDE_DIR gperftools/heap-profiler.h)
find_library(TCMALLOC_LIBRARY NAMES tcmalloc_and_profiler)
find_path(HIREDIS_INCLUDE_DIR hiredis/hiredis.h)
find_library(HIREDIS_LIBRARY NAMES hiredis)
find_path(GD_INCLUDE_DIR gd.h)
find_library(GD_LIBRARY NAMES gd)
find_program(THRIFT_COMPILER thrift)
find_path(THRIFT_INCLUDE_DIR thrift)
find_library(THRIFT_LIBRARY NAMES thrift)
if(CARES_INCLUDE_DIR AND CARES_LIBRARY)
message(STATUS "found cares")
endif()
if(CURL_FOUND)
message(STATUS "found curl")
endif()
if(PROTOBUF_FOUND)
message(STATUS "found protobuf")
endif()
if(TCMALLOC_INCLUDE_DIR AND TCMALLOC_LIBRARY)
message(STATUS "found tcmalloc")
endif()
if(ZLIB_FOUND)
message(STATUS "found zlib")
endif()
if(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARY)
message(STATUS "found hiredis")
endif()
if(GD_INCLUDE_DIR AND GD_LIBRARY)
message(STATUS "found gd")
endif()
if(THRIFT_COMPILER AND THRIFT_INCLUDE_DIR AND THRIFT_LIBRARY)
message(STATUS "found thrift")
endif()
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR})
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
message(STATUS "CXX_FLAGS = " ${CMAKE_CXX_FLAGS} " " ${CMAKE_CXX_FLAGS_${BUILD_TYPE}})
add_subdirectory(muduo/base)
add_subdirectory(muduo/net)
if(NOT CMAKE_BUILD_NO_EXAMPLES)
add_subdirectory(contrib)
add_subdirectory(examples)
else()
if(CARES_INCLUDE_DIR AND CARES_LIBRARY)
add_subdirectory(examples/cdns)
endif()
endif()
cmake示例
编译链接库
构建lib应该算是一个最常见的需求,现在假设我们新建一个简单库,只包含一个整数相加的函数。我们有两个文件add.h和add.cc。
//add.h
int add(int a, int b);
//add.cc
#include"add.h"
int add(int a, int b)
{
return a + b;
}
我们可以新建CMakeLists.txt如下
cmake_minimum_required(VERSION 2.6)
project(add)
set (add_SRCS
add.cc
)
add_library(add ${add_SRCS})
install(TARGETS add DESTINATION lib)
file(GLOB HEADERS "*.h")
install(FILES ${HEADERS} DESTINATION include/add)
这个命令不仅可以帮我们编译add这个lib,而且还可以将.a文件和.h文件安装到指令的目录下,这个由变量CMAKE_INSTALL_PREFIX控制,可用ccmake命令更改,default是/usr/local目录下。
编译可执行文件
现在假设我们要写一个程序,并且要使用上一步中的链接库,下面是程序代码及CMakeLists.txt
//test.cc
#include"add.h"
#include<iostream>
int main()
{
std::cout << add(1, 2) << std::endl;
}
cmake_minimum_required(VERSION 2.6)
project(main)
set (main_SRCS
test.cc
)
include_directories("/home/keviwu/add/include/add")
find_library(LIB_PATH add "/home/keviwu/add/lib")
if (NOT LIB_PATH)
message("libadd.a not find")
endif()
add_executable(main ${main_SRCS})
target_link_libraries(main ${LIB_PATH})
learn cmake的更多相关文章
- CMake速记
目录 CMake速记 我的demo 外部构建 基础语法 常用指令 环境变量 一些变量 参考文档 title: CMake速记 date: 2019/11/18 19:17:40 toc: true - ...
- vscode c++ cmake template project
VSCode configure C++ dev environment claim use CMake to build the project. For debugging, VSCode's C ...
- CMake 构建项目教程-简介
CMake 构建项目教程-简介 Linux 平台构建项目,选择了CLion作为C++的IDE,而CLion默认就是使用CMake构建项目,所以这里记录了CMake在构建项目过程的一些小知识. 1. 项 ...
- win10下VSCode+CMake+Clang+GCC环境搭建
win10下VSCode+CMake+Clang+GCC环境搭建 win10下VSCode+CMake+Clang+GCC环境搭建 安装软件 VSCode插件安装 新建文件夹, 开始撸代码 main. ...
- Reprint: CMake or Make
CMake vs Make https://prateekvjoshi.com/2014/02/01/cmake-vs-make/ Programmers have been using CMake ...
- 使用VSCode和CMake构建跨平台的C/C++开发环境
日前在学习制作LearnOpenGL教程的实战项目Breakout游戏时,希望能将这个小游戏开发成跨平台的,支持在多个平台运行.工欲善其事必先利其器,首先需要做的自然是搭建一个舒服的跨平台C/C++开 ...
- 使用cmake自动构建工程
公司引擎是用cmake根据目标平台来构建工程的,刚接触的时候深深体会到cmake的方便:如果目标平台是windows,它可以帮你自动构建出vs工程:如果是安卓,自动构建出eclipse工程,如果是IO ...
- CMake
使用CMake编译跨平台静态库 http://www.tuicool.com/articles/3uu2Yj cmake命令 安装.用法简介 https://fukun.org/archives/04 ...
- CMake学习笔记
C++开发者必备技能CMake 先简单介绍一下,CMake是一个跨平台的编译工具,它可以根据不用的平台,不同的编译环境,生成不同的MakeFile,从而控制编译的过程. 使用CMake的步骤: 1. ...
随机推荐
- Java中数组获取最大值
最大值获取:从数组的所有元素中找出最大值. 实现思路: 定义变量,保存数组0索引上的元素 遍历数组,获取出数组中的每个元素 将遍历到的元素和保存数组0索引上值的变量进行比较 如果数组元素的值大于了变量 ...
- Spring中xml文档的schema约束
最开始使用Spring框架的时候,对于其配置文件xml,只是网上得知其使用方法,而不明其意.最近想着寻根问底的探究一下.以下是本文主要内容: 1.配置文件示例. <?xml version= ...
- VMware WorkStation 用 VMTools 官方下载地址
每次安装 VMTools 都不成功,谷歌到了这个地址,特地分享. 先打开这个网址, 选择你的 VMware WorkStation 对应的版本号: http://softwareupdate.vmwa ...
- Java将数据以Excel文件形式导出后台代码实现
下面代码实现所需jar包: tomcat-embed-core-8.5.11.jar: commons-lang3-3.0.1.jar: commons-io-2.5.jar: poi-3.9.jar ...
- Ajax技术实战操练课堂学习笔记
ajax是什么 ? ajax(asynchronouse javascript and xml) 异步的javascript 和 xml 是7种技术的综合,它包含了七个技术( javascript x ...
- [luogu P2756 ] 飞行员配对方案问题 (最大流)
强行做裸题做了两个小时..我果然太水了QAQ 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 ...
- base64格式文件下载方法
下载图片时,接口返回的地址是base64格式的文件数据,因为页面需要把base64格式的数据转换为文件,再进行下载: 解决方案: 下载按钮: <el-button type="defa ...
- base64 编码的作用及原理
Base64编码的作用:由于某些系统中只能使用ASCII字符.Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法.它使用下面表中所使用的字符与编码. 而且base64特别适合在 ...
- ubuntu17.04中启动tnsorboard过程
ubuntu17.04中启动tnsorboard过程 首先激活tensorboard,找到根目录文件(注:跟tensorflow文件同级)找到tensorboard文件的main.py文件 然后找到程 ...
- POJ 3228 Gold Transportation
Gold Transportation Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on PKU. Ori ...