linux用cmake编译,CMake使用简介(forLinux)
cmake [选项]
cmake [选项]
因为source 目录在../ 所以指定../为源码目录。
-G:指定构建系统,当前只想创建Linux/Unix系统标准Makefile。所以指定为Unix
Makefile.
具体支持何种构建系统:man
cmake
可以看到类似入下内容:
Generators
The following generators are available
on this platform:
Ninja
= Generates build.ninja files
(experimental).
Unix Makefiles
= Generates standard UNIX makefiles.
CodeBlocks - Ninja
= Generates CodeBlocks project
files.
CodeBlocks - Unix
Makefiles = Generates CodeBlocks project files.
Eclipse CDT4 -
Ninja = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix
Makefiles
= Generates Eclipse CDT 4.0 project files.
KDevelop3
=
Generates KDevelop 3 project files.
KDevelop3 - Unix
Makefiles = Generates KDevelop 3 project
files.
这个CMakeLists.txt
内容中,构成可执行文件的文件个数很少,但如果源文件很多,则最好如Makefile中一样,指定一个源文件列表:
cmake_minimum_required (VERSION 2.6)
project (V4L2_Utils)
set (SRC_LIST main.cpp v4l2_util.cpp tran_data.cpp)
message (${SRC_LIST})
add_executable(V4L2_Utils ${SRC_LIST})
(注1)
1.2:
编译一个静态库,并使用这个静态库和main.cpp,最终再生成一个可执行程序:
即先生成libv4l2_utils.a.
main.cpp使用libv4l2_utils.a中的符号并最终生成V4L2_Utils.
CMakeLists.txt:
cmake_minimum_required (VERSION
2.6)
project (V4L2_Utils)
set (LIB_SRC_LIST
v4l2_util.cpp tran_data.cpp)
set (EXEC_SRC_LIST
main.cpp)
add_library(V4L2_Utils STATIC
${LIB_SRC_LIST})
add_executable(Test_V4L2
${EXEC_SRC_LIST})
target_link_libraries(Test_V4L2
V4L2_Utils)
说明:
add_library( [STATIC | SHARED |
MODULE][EXCLUDE_FROM_ALL]source1 source2 ... sourceN)
创建一个名为 name 的库文件,STATIC,
SHARED指定为静态或动态库。
库文件由源文件列表生成。
add_library(V4L2_Utils STATIC
${LIB_SRC_LIST})
生成一个静态库libV4l2_Utils.a 由v4l2_util.cpp tran_data.cpp生成
add_executable(Test_V4L2 ${EXEC_SRC_LIST})
可执行程序由哪些.o组成。
target_link_libraries(Test_V4L2 V4L2_Utils)
可执行程序Test_V4L2需要链接库V4L2_Utils
target_link_libraries( [item1 [item2 [...]]]
[[debug|optimized|general] ] ...)
将给定的库链接到目标target上。
1.3:
编译一个动态库,并使用这个动态和main.cpp,最终再生成一个可执行程序:
cmake_minimum_required (VERSION
2.6)
project (V4L2_Utils)
set (LIB_SRC_LIST
v4l2_util.cpp)
set (EXEC_SRC_LIST
main.cpp)
add_library(V4L2_Utils SHARED
${LIB_SRC_LIST})
add_executable(Test_V4L2
${EXEC_SRC_LIST})
target_link_libraries(Test_V4L2
V4L2_Utils)
只变化了STATIC-->SHARED
1.4:
指定include 路径:
main.cpp中,需要include "v4l2_util.h"
但这个头文件并不在src目录内,而是在include目录
include,
src为同级别目录。则main.cpp会找不到头文件。
所以,实际的CMakeLists.txt文件写法为:
cmake_minimum_required (VERSION
2.6)
project (V4L2_Utils)
set (LIB_SRC_LIST
v4l2_util.cpp)
set (EXEC_SRC_LIST
main.cpp)
set
(INCLUDE_DIRECTORIES ../include)
include_directories(${INCLUDE_DIRECTORIES})
add_library(V4L2_Utils SHARED
${LIB_SRC_LIST})
add_executable(Test_V4L2
${EXEC_SRC_LIST})
target_link_libraries(Test_V4L2
V4L2_Utils)
将头文件目录添加进去。
1.5:
添加第三方库和库路径:
如果libV4L2.so是以第三方库形式出现。不需要编译,它放在resource目录下。则需要制定搜索库路径
cmake_minimum_required
(VERSION 2.6)
project
(V4L2_Utils)
set (EXEC_SRC_LIST
main.cpp)
set (INCLUDE_DIRECTORIES
../include)
set (LINK_DIR
../../resource)
include_directories(${INCLUDE_DIRECTORIES})
link_directories(${LINK_DIR})
add_executable(Test_V4L2
${EXEC_SRC_LIST})
target_link_libraries(Test_V4L2
V4L2_Utils)
说明:
link_directories 指定连接器查找库的路径。
link_directories(directory1 directory2
...)
1.6:创建Release和Debug版本:
#set (CMAKE_BUILD_TYPE Release)
set (CMAKE_BUILD_TYPE Debug)
分别指定为Release或者Debug模式。区别在于:
Release: -O3
-DNDEBUG
Debug:-g
也可以不加在txt内。在产生Makefile时才加入:
cmake -DCMAKE_BUILD_TYPE=Release
1.7:
增加编译和链接选项:
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
CMAKE_EXE_LINKER_FLAGS
分别相当于:CFLAGS, CXXFLAGS, LDFLAGS。
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}
-DEMBED")
这种写法的好处是,不会覆盖CMAKE_CXX_FLAGS本来的信息。只是把需要添加的内容添加进去。
1.8:
多目录结构的cmake 使用:
V4L2_Utils实际的目录结构其实并不是所有源码都存放在src目录内。
它的目录结构是:
src: 存放生成库的源码。v4l2_util.cpp,
tran_data.cpp
test:存放使用库的测试程序: main.cpp
include: 存放头文件: v4l2_util.h
resource: 存放第三方库
build:存放编译过程的文件
build/lib: 存放生成的libv4l2_utils.so
build/bin:存放main.cpp所产生的测试程序可执行文件。
此时,可以采用顶层目录和每个有源码的目录中均创建CMakeLists.txt的方式来处理(和Makefile处理方式类似)
顶层目录的CMakeLists.txt 内容如下:
cmake_minimum_required (VERSION
2.6)
project (V4L2_Utils)
add_subdirectory(src lib)
add_subdirectory(test bin)
说明:
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
构建添加一个子路径。source_dir选项指定了CMakeLists.txt源文件和代码文件的位置。如果source_dir是一个相对路径,那么source_dir选项会被解释为相对于当前的目录,但是它也可以是一个绝对路径。binary_dir选项指定了输出文件的路径。如果binary_dir是相对路径,它将会被解释为相对于当前输出路径。
请注意两个相对路径的不同。因为Sam是在Build目录内执行cmake
..
source_dir算相对路径时,是从CMakeLists.txt算起。
所以src指的是当前 CMakeLists.txt所在路径下的src.
而bin, lib 指的是当前输出路径下的bin,lib. 也就是build/bin
build/lib
src
CMakeLists.txt :
set (LIB_SRC_LIST
v4l2_util.cpp)
set (CMAKE_BUILD_TYPE
Release)
include_directories(../include)
add_library(V4L2_Utils SHARED
${LIB_SRC_LIST})
test
CMakeLists.txt :
set (EXEC_SRC_LIST
main.cpp)
set (INCLUDE_DIRECTORIES
../include)
set (LINK_DIR
../../resource)
set (LINK_DIR "${LINK_DIR}
../../libs/")
set (CMAKE_BUILD_TYPE
Release)
include_directories(${INCLUDE_DIRECTORIES})
link_directories(${LINK_DIR})
add_executable(Test_V4L2
${EXEC_SRC_LIST})
target_link_libraries(Test_V4L2
V4L2_Utils)
这个做法一直不满意,其实有更好的做法
总结:
有了以下这些选项,写过Makefile的人可以很容易的使用CMake了。
生成可执行程序:
add_executable(Test_V4L2
${EXEC_SRC_LIST})
生成静态库
add_library(V4L2_Utils STATIC
${LIB_SRC_LIST})
生成动态库:
add_library(V4L2_Utils SHARED
${LIB_SRC_LIST})
指定头文件路径: -I
include_directories(${INCLUDE_DIRECTORIES})
指定库文件路径:
-L
link_directories(${LINK_DIR})
指定链接库:
-l
target_link_libraries(Test_V4L2
V4L2_Utils)
CFLAGS,CXXFLAGS,LDFLAGS:
CMAKE_C_FLAGS,CMAKE_CXX_FLAGS,CMAKE_EXE_LINKER_FLAGS
2. Debug和Release版本:
关键在于三个CMake设置:
CMAKE_BUILD_TYPE
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
当CMAKE_BUILD_TYPE设置为Debug。
则编译时采用CMAKE_CXX_FLAGS_DEBUG。
当CMAKE_BUILD_TYPE设置为Release。
则编译时采用CMAKE_CXX_FLAGS_RELEASE
cmake_minimum_required (VERSION
2.6)
project (CMAKE_Test)
add_executable(CMAKE_Test
src/banchmark.cpp)
#set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_DEBUG
"$ENV{CXXFLAGS} -O0 -Wall -g -ggdb
-Wno-unused-but-set-variable")
set(CMAKE_CXX_FLAGS_RELEASE
"$ENV{CXXFLAGS} -O3 -Wall -Wno-unused-but-set-variable")
3. CMake的交叉编译:
CMake是用来生成Makefile的,如果要交叉编译,需要告知CMake以下信息:
A. 当前是交叉编译。
B. 所用C/C++编译器。
C. 头文件,库文件目录,CFlags等。
#告知当前使用的是交叉编译方式,必须配置
SET(CMAKE_SYSTEM_NAMELinux)
#指定编译工具,一定要设置
#或交叉编译器使用绝对地址
SET(CMAKE_C_COMPILER"arm-linux-gcc")
#指定C++交叉编译器
SET(CMAKE_CXX_COMPILER"arm-linux-g++")
#不一定需要设置
#指定交叉编译环境安装目录...
SET(CMAKE_FIND_ROOT_PATH "...")
#从来不在指定目录下查找工具程序
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#只在指定目录下查找库文件
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
#只在指定目录下查找头文件
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
3.2:第三方库交叉编译实例:
思路:创建一个设置交叉编译的 xxx.cmake. 例如:ndk_clang.cmake, 或者armv7a.cmake. 用来分别针对NDK的clang编译器和ARMv7a指令集编译器。如此,则可以大致不修改CMakeLists.txt的同时,适配多种交叉编译平台。
然后在官方CMakeLists.txt中,include (xxx.cmake),注意,一定要include到project()后。
如:
project(libjpeg-turbo C)
set(VERSION 2.0.4)
include (ndk_sam_clang.cmake)
下面是ndk_sam_clang.cmake内容:
SET(CROSS_COMPILE 1)
IF(CROSS_COMPILE)
set(CMAKE_SYSTEM_NAME Linux)
set(NDK_PATH "/opt/android-ndk-r15c")
set(BUILD_TOOL "llvm")
set(BUILD_PLATFORM "linux-x86_64")
set(ANDROID_PLATFORM "android-23")
SET(TOOLCHAIN_DIR ${NDK_PATH}/toolchains/${BUILD_TOOL}/prebuilt/${BUILD_PLATFORM})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/clang++)
message (${CMAKE_CXX_COMPILER})
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/clang)
set(GNU_FLAGS "-mfloat-abi=softfp -mfpu=vfpv3-d16")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS} ")
set(CMAKE_C_FLAGS "${GNU_FLAGS} ")
set(CMAKE_SYSTEM_PROCESSOR "arm")
SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}
${NDK_PATH}/platforms/${ANDROID_PLATFORM}/arch-arm/include
${NDK_PATH}/platforms/${ANDROID_PLATFORM}/arch-arm/lib )
message("CMAKE__SYSTEM_PROCESSOR:" ${CMAKE_SYSTEM_PROCESSOR} )
ENDIF(CROSS_COMPILE)
注1:set
和message
set用来指定变量
如:
set (SRC_LIST main.cpp)
则变量SRC_LIST内容为main.cpp
${SRC_LIST} 则为取变量内容(与Bash类似)
message:用来显示变量
message (${SRC_LIST})
注2:
如何显示编译细节:
方法1:
在CMakeLists.txt中,
set(CMAKE_VERBOSE_MAKEFILE ON)
方法2:
有时不希望修改CMakeLists.txt文件,则可以在创建Makefile时加入:
cmake -DCMAKE_VERBOSE_MAKEFILE=ON
方法3:
有时连Makefile都不希望修改:
make VERBOSE=1
注2:相对路径问题:
set (LIBRARY_DIRECTORIES
../resource)
link_directories(${LIBRARY_DIRECTORIES})
这里会出警告:
This command specifies the relative
path
../resource
可以做如下处理:
set (LIBRARY_DIRECTORIES
../resource)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/${LIBRARY_DIRECTORIES})
注3:
https://cmake.org/
注4:
find_package()功能讲解:
例如:
find_package(Qt5Widgets)
可以被用来在系统中自动查找配置构建工程所需的程序库。在linux和unix类系统下这个命令尤其有用。CMake自带的模块文件里有大半是对各种常见开源库的find_package支持,支持库的种类非常多.
find_package( [version] [EXACT] [QUIET]
[[REQUIRED|COMPONENTS] [components...]]
[NO_POLICY_SCOPE])
查找并加载外来工程的设置。该命令会设置_FOUND变量,用来指示要找的包是否被找到了。如果这个包被找到了,与它相关的信息可以通过包自身记载的变量中得到。REQUIRED选项表示如果报没有找到的话,cmake的过程会终止,并输出警告信息
在REQUIRED选项之后,或者如果没有指定REQUIRED选项但是指定了COMPONENTS选项,在它们的后面可以列出一些与包相关的部件清单(components list)。
FIND_PACKAGE
每一个模块都会产生如下变量
_FOUND
_INCLUDE_DIR
_LIBRARY or _LIBRARIES
如果_FOUND为真,把_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中。
就会有变量Qt5Widgets_FOUND,Qt5Widgets_INCLUDE_DIRS等相应的变量生效。
例如:
find_package(catkin REQUIRED
COMPONENTS
roscpp
rospy
std_msgs)
如果找到catkin package. 则catkin_FOUND
被设置为true. catkin_INCLUDE_DIRS, catkin_LIBRARIES 被设置。
如果没找到,因为有REQUIRED. 所以会抱错。
注5:
pkg_check_modules讲解:
pkg_check_modules( [REQUIRED]
[]*)
检测所有给出的modules
pkg_check_modules(PC_OPENNI2 libopenni2)
if (NOT PC_OPENNI2_FOUND)
pkg_check_modules(PC_OPENNI2 REQUIRED openni2)
endif()
PC_OPENNI2_INCLUDE_DIRS, PC_OPENNI2_LIBRARY_DIRS 等被设置。
linux用cmake编译,CMake使用简介(forLinux)相关推荐
- gcc编译可执行文件和cmake编译可执行文件
gcc编译 gcc的下载(下载mingw,里面包含gcc) 下载安装MinGW-w64详细步骤(c/c++的编译器gcc的windows版,win10真实可用) gcc编译可执行文件 由源码转换为可执 ...
- linux cmake编译源码,linux安装mysql(源码)以及cmake编译
说明:mysql 5.5开始必须用cmake编译 系统环境archlinux,mysql版本5.5.27,cmake版本2.2.8 安装: (1).安装cmake.cmake是一款跨平台的编译工具 [ ...
- cmake教程(为什么要用cmake?)(cmake编译opencv)(就是个跨平台的编译工具Linux、windows)(很重要,必须得学)(报错解决方案)opencv编译
文章目录 cmake编译opencv源码 分割线 CMake:简介及工程应用,及为什么要用CMake,使用CMake自动构建工程 mark一下,回头更 cmake编译opencv源码 cmake官网: ...
- Linux源码安装mysql 5.6.12(cmake编译)
转载链接:http://www.2cto.com/database/201307/229260.html Linux源码安装mysql 5.6.12(cmake编译) 1.安装make编译器(默认系统 ...
- linux cmake编译安装mysql_Linux源码安装MySQL 5.6.12 (Cmake编译)
Linux源码安装MySQL 5.6.12 (Cmake编译) 1.安装make编译器(默认系统自带) 下载地址: tar zxvf make-3.82.tar.gz cd make-3.82 ./c ...
- Linux使用cmake编译项目,如何使用cmake在linux中构建Qt项目(How to build Qt project in linux with cmake)...
如何使用cmake在linux中构建Qt项目(How to build Qt project in linux with cmake) 我使用的是ubuntu 14.04,cmake 2.8.12.2 ...
- linux下QT工程调用opencv、libtorch,并用cmake编译,及其遇到的一些问题的解决方法
linux下QT工程调用opencv.libtorch,并用cmake编译: 文章目录 一.新建QT工程 二.编写CMakeLists.txt文件 三.各个文件的内容如下: 1.mainwindow. ...
- linux opengl配置编译,Linux下OpenGL的安装与cmake编译OpenGL程序
Linux下OpenGL的安装与cmake编译OpenGL程序 OpenGL安装 安装命令如下: $ sudo apt install build-essential $ sudo apt insta ...
- win10子系统linux下cmake编译32位程序
文章目录 Ubuntu 18运行32位程序 添加软件源 安装编译环境 编写CMakeLists.txt cmake编译 运行程序 SUSE 15.0运行32位程序 m32编译 添加软件源 安装qemu ...
最新文章
- python and or 与 | 的比较
- 张孝祥Java培训视频及孙鑫java视频网址
- maven上传本地仓库
- 小程序onload_小程序生命周期-基础篇
- 【Python】zip函数的使用
- mysql主从和dump_MySQL主从同步--原理及实现(一)
- Kubernetes 诞生七年,凭什么成为主流?
- Spring Boot整合Swagger3
- IDEA设置光标所在行背景色
- java.lang.NoSuchMethodError: org.jaxen.dom4j.DocumentNavigator.getInstance()【可能的解决办法】
- CoolShell-第4题
- ‘v-model‘ directives require the attribute value which is valid as LHS
- 《Adobe SiteCatalyst网站分析权威手册》一第1章 什么是Adobe SiteCatal0yst1.1 SiteCatalyst简史...
- 什么是B2B销售?如何有效地向其他企业销售
- mtk处理器和骁龙对比_3500元以内手机的绝杀?首款MTK 天玑1000处理器手机IQOO Z发布...
- 【一文学会】vue.js入门到放弃
- 使用JavaCV实现海康rtsp转rtmp实现无插件web端直播(无需转码,低资源消耗)
- getApplicationContext 详解
- 基于MindSpore的MASS网络实现
- php 读取excel中的内容到mysql 数据库
热门文章
- Python Tricks(五)—— 计算 list of lists 的长度(元素个数)
- 【剑指 offer】(二十九)—— 数组中出现次数超过一半的数字(及该数字出现的次数)
- 机器学习常用公式(二)
- matplotlib —— fill between
- for循环语句例子 python_Python for循环语句一般形式例子
- 零基础学python书籍-0基础学python,有什么教程或者书可以推荐吗?
- python官网下载文件-使用Python下载文件的简单示例
- python教程视频下载-python怎么下载视频
- python有趣小程序-python好玩的小程序
- python-成都Python课程