cmake 添加头文件目录,链接动态、静态库

罗列一下cmake常用的命令。

CMake支持大写、小写、混合大小写的命令。

1. 添加头文件目录INCLUDE_DIRECTORIES

语法:

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用。

include_directories(../../../thirdparty/comm/include)

  

2. 添加需要链接的库文件目录LINK_DIRECTORIES

语法:

link_directories(directory1 directory2 ...)

它相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。

link_directories("/home/server/third/lib")

3. 查找库所在目录FIND_LIBRARY

语法:

A short-hand signature is:

find_library (<VAR> name1 [path1 path2 ...])
The general signature is: find_library (
<VAR>
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)

  

例子如下:

FIND_LIBRARY(RUNTIME_LIB rt /usr/lib  /usr/local/lib NO_DEFAULT_PATH)

cmake会在目录中查找,如果所有目录中都没有,值RUNTIME_LIB就会被赋为NO_DEFAULT_PATH

4. 添加需要链接的库文件路径LINK_LIBRARIES

语法:

link_libraries(library1 <debug | optimized> library2 ...)
# 直接是全路径
link_libraries(“/home/server/third/lib/libcommon.a”)
# 下面的例子,只有库名,cmake会自动去所包含的目录搜索
link_libraries(iconv) # 传入变量
link_libraries(${RUNTIME_LIB})
# 也可以链接多个
link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

  

可以链接一个,也可以多个,中间使用空格分隔.

5. 设置要链接的库文件的名称TARGET_LINK_LIBRARIES 

语法:

target_link_libraries(<target> [item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
# 以下写法都可以:
target_link_libraries(myProject comm) # 连接libhello.so库,默认优先链接动态库
target_link_libraries(myProject libcomm.a) # 显示指定链接静态库
target_link_libraries(myProject libcomm.so) # 显示指定链接动态库 # 再如:
target_link_libraries(myProject libcomm.so)  #这些库名写法都可以。
target_link_libraries(myProject comm)
target_link_libraries(myProject -lcomm)

  

6. 为工程生成目标文件
语法:
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])

简单的例子如下:

add_executable(demo
main.cpp
)
6. 最后贴一个完整的例子
cmake_minimum_required (VERSION 2.6)

INCLUDE_DIRECTORIES(../../thirdparty/comm)

FIND_LIBRARY(COMM_LIB comm ../../thirdparty/comm/lib NO_DEFAULT_PATH)
FIND_LIBRARY(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH) link_libraries(${COMM_LIB} ${RUNTIME_LIB}) ADD_DEFINITIONS(
-O3 -g -W -Wall
-Wunused-variable -Wunused-parameter -Wunused-function -Wunused
-Wno-deprecated -Woverloaded-virtual -Wwrite-strings
-D__WUR= -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DTIXML_USE_STL
) add_library(lib_demo
cmd.cpp
global.cpp
md5.cpp
) link_libraries(lib_demo)
add_executable(demo
main.cpp
) # link library in static mode
target_link_libraries(demo libuuid.a)

  

原文链接:http://blog.csdn.net/x_r_su/article/details/52927768


Cmake知识----编写CMakeLists.txt文件编译C/C++程序

1.CMake编译原理

CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多。CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库(so(shared object))。因此CMake的编译基本就两个步骤:

cmake
make

  

make根据生成makefile文件,编译程序。

2.使用Cmake编译程序

我们编写一个关于开平方的C/C++程序项目,即b= sqrt(a),以此理解整个CMake编译的过程。

a.准备程序文件

文件目录结构如下:

.
├── build
├── CMakeLists.txt
├── include
│ └── b.h
└── src
├── b.c
└── main.c

头文件b.h,如下所示:

#ifndef B_FILE_HEADER_INC
#define B_FIEL_HEADER_INC #include<math.h> double cal_sqrt(double value); #endif

  

头文件b.c,如下所示:

#include "../include/b.h"

double cal_sqrt(double value)
{
return sqrt(value);
}

  

main.c主函数,如下所示:

#include "../include/b.h"
#include <stdio.h>
int main(int argc, char** argv)
{
double a = 49.0;
double b = 0.0; printf("input a:%f\n",a);
b = cal_sqrt(a);
printf("sqrt result:%f\n",b);
return 0;
}

  

b.编写CMakeLists.txt

接下来编写CMakeLists.txt文件,该文件放在和src,include的同级目录,实际方哪里都可以,只要里面编写的路径能够正确指向就好了。CMakeLists.txt文件,如下所示:

#1.cmake verson,指定cmake版本
cmake_minimum_required(VERSION 3.2) #2.project name,指定项目的名称,一般和项目的文件夹名称对应
PROJECT(test_sqrt) #3.head file path,头文件目录
INCLUDE_DIRECTORIES(
include
) #4.source directory,源文件目录
AUX_SOURCE_DIRECTORY(src DIR_SRCS) #5.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
SET(TEST_MATH
${DIR_SRCS}
) #6.add executable file,添加要编译的可执行文件
ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_MATH}) #7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)

  

CMakeLists.txt主要包含以上的7个步骤,具体的意义,请阅读相应的注释。

c.编译和运行程序

准备好了以上的所有材料,接下来,就可以编译了,由于编译中出现许多中间的文件,因此最好新建一个独立的目录build,在该目录下进行编译,编译步骤如下所示:

mkdir build
cd build
cmake ..
make

  

操作后,在build下生成的目录结构如下:

├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.2.2
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ └── CMakeCCompilerId.c
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ └── CMakeCXXCompilerId.cpp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── feature_tests.bin
│ │ ├── feature_tests.c
│ │ ├── feature_tests.cxx
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ ├── TargetDirectories.txt
│ │ └── test_sqrt.dir
│ │ ├── build.make
│ │ ├── C.includecache
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ ├── progress.make
│ │ └── src
│ │ ├── b.c.o
│ │ └── main.c.o
│ ├── cmake_install.cmake
│ ├── Makefile
│ └── test_sqrt
├── CMakeLists.txt
├── include
│ └── b.h
└── src
├── b.c
└── main.c

  

注意在build的目录下生成了一个可执行的文件test_sqrt,运行获取结果如下:

命令:
./test_sqrt
结果:
input a:49.000000
sqrt result:7.000000

  

d.源码

地址test_sqrt.tar.gz

3.参考资料

[1]. CMake 使用方法 & CMakeList.txt

https://www.cnblogs.com/cv-pr/p/6206921.html


aux_source_directory 查找在某个路径下的所有源文件。

aux_source_directory(< dir > < variable >)

  搜集所有在指定路径下的源文件的文件名,将输出结果列表储存在指定的变量中。该命令主要用在那些使用显式模板实例化的工程上。模板实例化文件可以存储在Templates子目录下,然后可以使用这条命令自动收集起来;这样可以避免手工罗列所有的实例。

  使用该命令来避免为一个库或可执行目标写源文件的清单,是非常具有吸引力的。但是如果该命令貌似可以发挥作用,那么CMake就不需要生成一个感知新的源文件何时被加进来的构建系统了(也就是说,新文件的加入,并不会导致CMakeLists.txt过时,从而不能引起CMake重新运行。——译注)。正常情况下,生成的构建系统能够感知它何时需要重新运行CMake,因为需要修改CMakeLists.txt来引入一个新的源文件。当源文件仅仅是加到了该路径下,但是没有修改这个CMakeLists.txt文件,使用者只能手动重新运行CMake来产生一个包含这个新文件的构建系统。

cmakelist的更多相关文章

  1. Android Studio中的CmakeList NDK配置

    Android Studio2.2之后直接可以在创建工程时添加NDK支持了,添加之后,main文件夹下会多出一个native-lib.cpp这个文件,如果只为了一个简单的NDK接口,貌似这就结束了.直 ...

  2. CMakeList.txt设置OpenCv路径

    源文件imageBasics.cpp #include <iostream> #include <chrono> using namespace std; #include & ...

  3. 单个源文件下CmakeList.txt

    单个源文件下CmakeList.txt 1. main.c代码 & CmakeLists.txt 文件内容 在任意自己选定的目录下(t1/)编写main.c 与 CmakeLists.txt ...

  4. c++ cmakelist 详解

    基本元素 首先cmaklist必须包括以下几个部分: #工程名 project(study_case) #cmake最低版本需求 cmake_minimum_required(VERSION 2.8. ...

  5. ROS初级教程 cmake cmakelist.txt 的编写教程

    有很多 的时候我们使用别人的程序包.然后添加东西的时候缺少什么东西,会使程序编译不过去,甚至无法运行,接下来介绍一下cmakelist.txt 的每一行的作用.为了以后添加和修改方便. 2.整体结构和 ...

  6. CMake 基本用法--写CMakeList.txt

    http://techbase.kde.org/Development/Tutorials/CMake_(zh_CN) http://www.cmake.org/Wiki/CMake 这一章将从软件开 ...

  7. cmakelist 定义字符串,替换到脚本中。

    cmake_minimum_required(VERSION 2.6 FATAL_ERROR) cmake_policy(VERSION 2.6) # . Project Name project(s ...

  8. CMakeList相关

    cmake使用示例与整理总结 http://blog.csdn.net/wzzfeitian/article/details/40963457/ 对应的demo:https://github.com/ ...

  9. CMake 使用方法 & CMakeList.txt<转>

    CMake 使用方法 & CMakeList.txt cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的make ...

随机推荐

  1. pxe无人值守自动安装

    rpm -ivh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpmyum listyum upda ...

  2. Spring MVC工作流程图

    图一   图二    Spring工作流程描述       1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获:       2. Disp ...

  3. ubuntu 18.04在更新软件库时出现E: Release file for http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease is not valid yet...

    1.完整的错误信息如下: E: Release file for http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease i ...

  4. <The old man and the sea>

    Every day is a new day. It is better to be lucky. But i would rather be exact. Then when luck comes ...

  5. ThreadLocal 从源码角度简单分析

    目录 ThreadLcoal源码浅析 ThreadLocal的垃圾回收 Java引用 ThreadLocal的回收 各线程中threadLocalMap的回收 内存泄露问题 总结 参考 ThreadL ...

  6. 使用vs的时候,遇到这个:当前不会命中断点 还没有为该文档加载任何符号

    一 http://stackoverflow.com/questions/2155930/fixing-the-breakpoint-will-not-currently-be-hit-no-symb ...

  7. 酷到没朋友—— Cafflano便携式手磨手冲一体壶

    又一款外国新玩具~ 设计紧凑,手磨.滤架.滤壶融合的毫无ps痕迹! 简直是出差旅行,杀人越货必备良品!废话不多说,上图: 肿么样,一壶在手,天下我有~~~哈哈哈~~~

  8. JavaScript对象、JSON对象、JSON字符串的区别

    一.首先看下什么是JSON JSON:JavaScript Object Natation,JavaScript对象的表现形式,已经发展成一种轻量级的数据交换格式. JavaScript对象的表现形式 ...

  9. 20165332 2017-2018-2《Java程序设计》课程总结

    20165332 2017-2018-2<Java程序设计>课程总结 一.每周作业及实验报告链接汇总 我期望的师生关系 学习基础和c语言基础调查 Linux安装及命令入门 第一周学习总结 ...

  10. 设计模式--命令模式C++实现

    命令模式C++实现 1定义 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求队列或者记录请求日志,可以提供命令的撤销和恢复功能 2类图 角色描述: Receiver接受者角色,就 ...