文档章节

使用cmake编译C语言项目时使用第三方库

小代码2016
 小代码2016
发布于 2015/08/12 14:04
字数 1627
阅读 5814
收藏 24

关于cmake的安装,CMakeLists.txt的语法规则,CMakeLists.txt的各种配置选项等复杂而专业的知识,限于本人能力,这里不再说明

演示使用glibc2.0库

一 项目目录


laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ tree
.
├── bin
├── CMakeLists.txt
├── include
│   ├── hello.h
│   └── sum.h
├── lib
└── src
    ├── CMakeLists.txt
    ├── hello
    │   ├── CMakeLists.txt
    │   └── hello.c
    ├── main
    │   ├── CMakeLists.txt
    │   └── main.c
    └── sum
        ├── CMakeLists.txt
        └── sum.c

7 directories, 10 files
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$



在hello,main,sum三个子目录中,除hello外,其他目录都没有使用到第三方库,可以再这里查看再没有第三方库时,如何使用cmake。实际上这个例子就是在我之前的“cmake之一个小例子”这篇博文的基础上添加了一个hello目录,在其中使用了glibc库。hello.c的代码来自:http://blog.chinaunix.net/uid-25696269-id-466217.html



二 源代码

include/sum.h


/*
 * sum.h
 *
 *  Created on: 2015年8月11日
 *      Author: laolang
 */

#ifndef INCLUDE_SUM_H_
#define INCLUDE_SUM_H_

int sum( int a, int b);

#endif /* INCLUDE_SUM_H_ */

include/hello.h



/*
 * hello.h
 *
 *  Created on: 2015年8月11日
 *      Author: laolang
 */

#ifndef INCLUDE_HELLO_H_
#define INCLUDE_HELLO_H_

void hello();

#endif /* INCLUDE_HELLO_H_ */




main/main.c


#include<stdio.h>
#include"../../include/sum.h"
#include"../../include/hello.h"
int main(void){
	int a = 0;
	int b = 0;
	puts("请输入两个整数:");
	scanf("%d %d",&a,&b);
	printf("%d + %d = %d\n",a,b,sum(a,b));
	hello();
	printf("\n\nHello World!\n");
	return 0;
}



sum/sum.c


#include"../../include/sum.h"
int sum( int a, int b){
	return a + b;
}




hello/hello.c


#include<stdio.h>
#include<glib.h>

#include"../../include/hello.h"

void hello(){
	g_printf("\n\nHello World! from glibc2.0\n");
}




三 CMakeLists.txt

顶层CMakeLists.txt


# 顶层CMakeLists.txt

# 定义工程名称
project(HELLO)
 
# 定义子目录src,用以递归的调用src中的MakeLists.txt
add_subdirectory(src)


src/CMakeLists.txt


# src CMakeLists.txt

# 定义子目录
add_subdirectory(main)
 
#定义子目录
add_subdirectory(sum)

add_subdirectory(hello)



src/main/CMakeLists.txt


# main CMakeLists.txt

# 源文件列表
set(SRC_LIST main.c)
 
# 头文件列表
include_directories(${HELLO_SOURCE_DIR}/include)
 
# 设置生成的可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${HELLO_SOURCE_DIR}/bin)
 
# 生成的可执行文件
add_executable(test ${SRC_LIST})
 
# 所需要的库文件的目录
link_directories(${HELLO_SOURCE_DIR}/lib)
 
# 需要链接的库文件
target_link_libraries(test sum hello)



src/sum/CMakeLists.txt


# sum CMakeLists.txt

# 设置编译器
set(CMAKE_C_COMPILER gcc)
 
# 源文件列表
set(SRC_LIST sum.c)
 
# 头文件目录
include_directories(${HELLO_SOURCE_DIR}/include)
 
# 设置生成的库文件的路径
set(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)
 
# 生成的库文件
add_library(sum STATIC ${SRC_LIST})



src/hello/CMakeLists.txt


# hello CMakeLists.txt
 
# 设置编译器
set(CMAKE_C_COMPILER gcc) 


# 源文件列表
set(SRC_LIST hello.c) 

# 头文件目录
include_directories(${HELLO_SOURCE_DIR}/include) 

# 设置生成的库文件的路径
set(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)


# 所需要的glibc(gtk)库文件的目录
include_directories(
		/usr/include/glib-2.0
		/usr/lib/x86_64-linux-gnu/glib-2.0/include
)
# 生成的库文件
add_library(hello STATIC ${SRC_LIST}) 

# 需要链接的glibc(gtk)库文件
target_link_libraries(hello 
		glib-2.0 
)



四  cmake && make


laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ tree
.
├── bin
├── CMakeLists.txt
├── include
│   ├── hello.h
│   └── sum.h
├── lib
└── src
    ├── CMakeLists.txt
    ├── hello
    │   ├── CMakeLists.txt
    │   └── hello.c
    ├── main
    │   ├── CMakeLists.txt
    │   └── main.c
    └── sum
        ├── CMakeLists.txt
        └── sum.c

7 directories, 10 files
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ mkdir build
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ cd build/
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake/build$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) at src/main/CMakeLists.txt:13 (add_executable):
  Policy CMP0037 is not set: Target names should not be reserved and should
  match a validity pattern.  Run "cmake --help-policy CMP0037" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  The target name "test" is reserved or not valid for certain CMake features,
  such as generator expressions, and may result in undefined behavior.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.3)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
CMake Warning (dev) at src/main/CMakeLists.txt:13 (add_executable):
  Policy CMP0003 should be set before this line.  Add code such as

    if(COMMAND cmake_policy)
      cmake_policy(SET CMP0003 NEW)
    endif(COMMAND cmake_policy)

  as early as possible but after the most recent call to
  cmake_minimum_required or cmake_policy(VERSION).  This warning appears
  because target "test" links to some libraries for which the linker must
  search:

    glib-2.0

  and other libraries with known full path:

    /home/laolang/code/cmake/eclipse/HelloCMake/lib/libsum.a

  CMake is adding directories in the second list to the linker search path in
  case they are needed to find libraries from the first list (for backwards
  compatibility with CMake 2.4).  Set policy CMP0003 to OLD or NEW to enable
  or disable this behavior explicitly.  Run "cmake --help-policy CMP0003" for
  more information.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /home/laolang/code/cmake/eclipse/HelloCMake/build
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake/build$ make
Scanning dependencies of target hello
[ 16%] Building C object src/hello/CMakeFiles/hello.dir/hello.o
[ 33%] Linking C static library ../../../lib/libhello.a
[ 33%] Built target hello
Scanning dependencies of target sum
[ 50%] Building C object src/sum/CMakeFiles/sum.dir/sum.o
[ 66%] Linking C static library ../../../lib/libsum.a
[ 66%] Built target sum
Scanning dependencies of target test
[ 83%] Building C object src/main/CMakeFiles/test.dir/main.o
[100%] Linking C executable ../../../bin/test
[100%] Built target test
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake/build$ cd ..
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ ./bin/test 
请输入两个整数:
2 3
2 + 3 = 5


Hello World! from glibc2.0


Hello World!
laolang@laolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$


五 一点问题

include_directories和target_link_libraries中的参数来源:pkg-config --cflags glibc-2.0 pkg-config --cflags glibc-2.0

在cmake的压缩包的share/cmakex.x/Modules中,有很多的FindXXX.cmake文件,也就是cmake提供好的关于第三方库的finder,于是我在这个http://blog.csdn.net/dbzhang800/article/details/6329314  博客 中找到了使用方法,但是我并没有成功,提示glib.h没有找不到。在技术问答中经人提醒,使用完整的绝对路径,也就是使用pkg-config --cflags gblic-2.0和pkg-config --libs gblic-2.0的输出分别作为include_directories和target_link_libraries的参数。这样做虽然可以解决问题,但是这样肯定是有问题的,可以看到cmake命令的输出中有一大堆的警告,对于不想看见警告的我,这是很无奈的事情。还有其他问题,比如库升级了,改名字了,或者连安装路径都换了,项目不大还好,项目比较庞大和复杂时,那么修改CMakeLists.txt将是十分痛苦的事情。我之所以使用CMakeLists.txt的原因不外乎两个:1 快捷 2 跨平台,而我的这种方法一是一旦库改变修改不快捷,二是换个系统就要修改CMakeLists.txt,这是不行的。

希望cmake高手可以提供一个例子,最好能有cmake自带的finder和cmake未包含的第三方库。谢谢!










© 著作权归作者所有

小代码2016
粉丝 46
博文 328
码字总数 153495
作品 0
安阳
程序员
私信 提问
加载中

评论(6)

小代码2016
小代码2016 博主

引用来自“新年”的评论

cmake总比make要好一些
我最近开始用xmake了,你也可以试试,就是IDE的支持不太好
新年
新年
cmake总比make要好一些
小代码2016
小代码2016 博主

引用来自“wzugang”的评论

cmake这东西太麻烦了,还有人用?
是麻烦了一点,不过用着很好用,如果我写的代码分几个目录,每个目录再链接不同的库,那Makefiles写起来不是更麻烦
wzugang
wzugang
cmake这东西太麻烦了,还有人用?
小代码2016
小代码2016 博主

引用来自“magiclogy”的评论

首先是搜索第三方库的问题,幸运的是不是用的Windows,所以可以直接使用FindPkgConfig模块,参考文档cmake --help-module FindPkgConfig。
至于警告的问题,你看了警告的正文么?cmake_minimum_required没有写,add_executable设置的target的名称不可以是test。
我就不明白为什么很多人只看到编译器报错,却不看报什么错。。。
原因很简单,看不懂英文。当然我的CMakeLists.txt肯定要改进,现在先能运行再说 谢谢你的翻译
m
magiclogy
首先是搜索第三方库的问题,幸运的是不是用的Windows,所以可以直接使用FindPkgConfig模块,参考文档cmake --help-module FindPkgConfig。
至于警告的问题,你看了警告的正文么?cmake_minimum_required没有写,add_executable设置的target的名称不可以是test。
我就不明白为什么很多人只看到编译器报错,却不看报什么错。。。
cmake构建C++项目避免编译时对第三方库头文件进行依赖检查

最近有同事反应一个使用cmake构建的C++项目编译很慢,具体表现是随便修改一个很简单的cpp源文件后,重新编译生成可执行文件的时间需要用3分钟左右。统计了一下整个增量编译过程各阶段耗时,发...

shzwork
04/17
19
0
AndroidStudio用Cmake方式编译NDK代码(cmake配置.a库)

AndroidStudio用Cmake方式编译NDK代码(cmake配置.a库) 1.cmake是什么? CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的mak...

shzwork
06/05
61
0
xmake vs cmake对比分析

xmake vs cmake对比分析 waruqi 1分钟前暂无评论 阅读 1 次 首先,不得不承认,cmake很强大,发展了这么多年,整个生态已经相当完善,功能也相当丰富,这点xmake目前是比不了的。 当初我做x...

waruqi
06/04
0
0
cmake 学习笔记(三)

接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用。 学习一下cmake的 finder。 finder是神马东西? 当编译一个需要使用第三方库的软件时,我们需要知道: 去哪儿找头...

晨曦之光
2012/05/08
202
0
在 linux 下使用 CMake 构建应用程序

CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文...

红薯
2009/02/06
885
0

没有更多内容

加载失败,请刷新页面

加载更多

搭建高可用MongoDB集群(分片)

搭建高可用MongoDB集群(分片) MongoDB基础请参考:https://blog.51cto.com/kaliarch/2044423 MongoDB(replica set)请参考:https://blog.51cto.com/kaliarch/2044618 一、概述 1.1 背景 ......

linjin200
13分钟前
3
0
CDH6.0.1集成tez-0.9.1计算引擎

参考文章: https://www.jianshu.com/p/9fb9f32e1f0f https://www.baidu.com/link?url=OgpwasnZi7H1dySN2T111sseEWDBaCCTC3DFV61G7756YbrkJCA8Y3UFaueyqnfN&wd=&eqid=daeb8b3500049cf3000000......

Sheav
15分钟前
4
0
Vue内置指令的使用

v-model(数据绑定) v-model常用于表单数据的双向绑定,它本质上是一个语法糖。它主要的有两种应用: 在文本框、多行文本、input的下拉框、单选按钮、复选框中的应用 <div id="app"> ...

凌兮洛
16分钟前
3
0
外部来源应用检查-烦死了,终于找到解决设置了

Android 连接usb调试应用的时候: 华为关闭方法:1、设置-安全-更多安全设置,关掉外部来源应用检查。2、设置-系统-开发人员选项-关闭“监控ADB安装应用” 不知道OPPO 怎么关闭的?...

QGlaunch
17分钟前
4
0
6个K8s日志系统建设中的典型问题,你遇到过几个?

作者 | 元乙 阿里云日志服务数据采集客户端负责人,目前采集客户端 logtail 在集团百万规模部署,每天采集上万应用数 PB 数据,经历多次双 11、双 12 考验。 导读:随着 K8s 不断更新迭代,使...

阿里云官方博客
19分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部