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

关于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未包含的第三方库。谢谢!










转载于:https://my.oschina.net/iamhere/blog/491193

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值