cmake、MakeFile、shell编译自动查找依赖库

cmake自动查找依赖库

写代码的时候经常要在编译选项中添加依赖库,有的库熟,有的库不熟。如果找不到库我们该怎么办?如果换了个别的电脑需要依赖库了我们该怎么办?

pkg-config

简介

  • pkg-config是编译应用程序和库时使用的辅助工具。它可以帮助您在命令行中插入正确的编译器选项,以便应用程序可以使用。例如pkg-config --libs --cflags glib-2.0,而不是编码写死到哪个路径下找到glib库(或其他库)

  • pkg-config可用与列举出某个库的相关信息,比如此库的路径、相关头文件路径等,这在程序编译时将非常有用。例如,现在要编译一个依赖librtmp.so库的程序。去哪找librtmp.so相关的头文件呢?librtmp.so库又在哪呢?这是一个大问题,但有了pkg-config后这些都不是问题。

pkg-config使用说明

在Makefile中使用pkg-config

参考demo

FLAGS=$(shell pkg-config --libs --cflags xxx yyy ...)

xxx,yyy替换成需要链接的库

在shell脚本中使用pkg-config

参考demo

gcc -o target \
    xxx.c xxx.h yyy.c ... \
    `pkg-config --cflags --libs aaa bbb`

xxx.c xxx.h yyy.c替换成源文件 aaa bbb替换成需要链接的库

终端中使用pkg-config查找依赖库

pkg-config常用参数:

  • –-list-all 列出所有已安装的共享库
  • -–cflags 列出指定共享库的预处理和编译flag。
  • -–libs 列出指定共享库的链接flag。

举个栗子,查找一下电脑里是否有安装gio-unix-2.0库,以及需要包含的头文件位置、依赖库

pkg-config --list-all | grep gio-unix-2.0

pkg-config –cflags –libs gio-unix-2.0 查看电脑里是否有库,输出如下

gio-unix-2.0 GIO unix specific APIs – unix specific headers for glib I/O library

pkg-config --cflags --libs gio-unix-2.0

输出库需要包含的头文件位置、依赖库

-pthread -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -lgio-2.0 -lgobject-2.0 -lglib-2.0

可以知道需要包含gio-2.0、gobject-2.0、glib-2.0三个库 需要包含头文件地址如下

-I/usr/include/gio-unix-2.0/

-I/usr/include/glib-2.0

-I/usr/lib/i386-linux-gnu/glib-2.0/include

cmake中自动寻找库

上文介绍了pkg-config,pkg-config自动寻找库的功能很强大但是无法在cmake中使用,那么cmake中有没有类似的工具呢?答案是,有的!

FindPkgConfig【CMake的pkg-config模块】

cmake官方FindPkgConfig说明

cmake官方说明2号

参考文档3号

pkg_check_modules(<PREFIX> [REQUIRED] [QUIET] <MODULE> [<MODULE>]*)

检查所有给出的模块

pkg_search_module(<PREFIX> [REQUIRED] [QUIET] <MODULE> [<MODULE>]*)

检查所有给出的模块,并使用找到的第一个

  • 如果设置了 REQUIRED 参数,未找到模块时宏将错误并失败
  • 如果设置了 QUIET 参数,将不打印状态信息。

cmake中自动寻找库实践

还是包含gio-unix-2.0库,上文使用pkg-config工具我们知道gio-unix-2.0还依赖gio-2.0、gobject-2.0、glib-2.0三个库。

首先使用FIND_PACKAGE将FindPkgConfig包含进来

FIND_PACKAGE (PkgConfig REQUIRED)

然后使用PKG_CHECK_MODULES查找依赖库

PKG_CHECK_MODULES (GLIB2 REQUIRED glib-2.0>=2.40)
PKG_CHECK_MODULES (GIO REQUIRED gio-2.0>=2.40)
PKG_CHECK_MODULES (GIO-UNIX REQUIRED gio-unix-2.0>=2.40)

包含需要依赖的头文件

include_directories(${GLIB2_INCLUDE_DIRS})
include_directories(${GIO_INCLUDE_DIRS})
include_directories(${GIO-UNIX_INCLUDE_DIRS} )

最后链接这些依赖库

TARGET_LINK_LIBRARIES(xxx  aaa bbb ccc )

xxx:目标文件target

aaa bbb ccc:需要链接的库

输出效果如下

— Found PkgConfig: /usr/bin/pkg-config (found version “0.29.1”)

— Checking for module ‘glib-2.0>=2.40’

— Found glib-2.0, version 2.48.2

— Checking for module ‘gio-2.0>=2.40’

— Found gio-2.0, version 2.48.2

— Checking for module ‘gio-unix-2.0>=2.40’

— Found gio-unix-2.0, version 2.48.2

给出几个demo作为参考

demo0

demo1

cmake_minimum_required(VERSION 2.8)
project(helloworld)
add_executable(helloworld hello.c)
find_package (BZip2)
if (BZIP2_FOUND)
  include_directories(${BZIP_INCLUDE_DIRS})
  target_link_libraries (helloworld ${BZIP2_LIBRARIES})
endif (BZIP2_FOUND)

demo2

find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
...
target_link_libraries(testapp ${SDL2_LIBRARIES})
target_include_directories(testapp PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(testapp PUBLIC ${SDL2_CFLAGS_OTHER})

demo3

demo4

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.