linux autotools案列强化(使用autotools生成库文件)

项目资料:
linux autotools案列强化(使用autotools生成库文件)_第1张图片

  • csdn链接:linux autotools工具生成库文件

  • github链接:暂无

1、目标:项目能够生成 .a .so库文件,并能够顺利执行make install操作

1)生成库文件主要关注src/Makefile.am中的lib_LTLIBRARIES关键字即可
2)make install的安装目录取决于Makefile.am目录中DESTDIR变量,读者可自行翻阅生成的Makefile文件

2、项目的README文件

1、命令行手动编译 gcc test/main.c src/show-notify.h src/show-notify.c -I./src `pkg-config --cflags --libs glib-2.0 gdk-2.0` -lnotify

2、本篇重点关注对象:
	- src目录下Makefile.am文件中
		-- 之前项目中的noinst_LTLIBRARIES 变成了lib_LTLIBRARIES;后者表示最终要生成库文件,前者只生成中间文件即可。
		-- _includedir 条目指定了make install操作时头文件被安装的目录
		-- _include_HEADERS 条目指定了make install操作时要被安装的头文件有哪些
			--- _includedir 和 _include_HEADERS 应该成对出现,否则编译会报错
	- src 和 test子目录中Makefile.am文件最后出现的 DESTDIR 变量
		-- DESTDIR变量在生成的Makefile文件中默认值为空
		   即make install操作默认会将库文件与头文件安装到系统目录 /usr/local/
		-- 如果给DESTDIR赋值了,如 DESTDIR = $(abs_top_srcdir)
		   则make install会将库文件和头文件安装到项目根目录下的 usr/local/ 目录下。

3、项目的configure.ac文件

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
#项目名,版本号,联系方式
AC_INIT([notify-lib], [1.0], [[email protected]])
#使用automake工具,subdir-objects表示多目录编程
AM_INIT_AUTOMAKE(subdir-objects)
#指定$(top_srcdir)的值
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.编译器检测
AC_PROG_CC
AC_PROG_CPP
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
#制作.a/.so库需要
AC_PROG_LIBTOOL

LIBNOTIFY_REQUIRED_VERSION=0.7.0
GLIB_REQUIRED_VERSION=2.17.3

dnl ------------------------------
dnl check for libnotify 使用pkg-config定义LIBNOTIFY的相关变量
dnl ------------------------------
PKG_CHECK_MODULES(LIBNOTIFY,libnotify >= $LIBNOTIFY_REQUIRED_VERSION)
AC_SUBST(LIBNOTIFY_CFLAGS)
AC_SUBST(LIBNOTIFY_LIBS)

dnl ------------------------------
dnl check for glib-2.0 使用pkg-config定义GLIB2的相关变量
dnl ------------------------------
PKG_CHECK_MODULES(GLIB2,glib-2.0 >= $GLIB_REQUIRED_VERSION)
AC_SUBST(GLIB2_CFLAGS)
AC_SUBST(GLIB2_LIBS)

# Checks for libraries.
AC_CHECK_LIB([glib-2.0],[notify])

# Checks for header files.
AC_CHECK_HEADERS([glib.h],[libnotify/notify.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions. 要生成Makefile文件的目录均在这里列出来
AC_CONFIG_FILES([Makefile
                src/Makefile
                test/Makefile])

AC_OUTPUT

4、项目的总Makefile.am文件

NULL =

#项目中存在空目录time,因为其不需要参与编译,所以这里不需要列举出来
#test目录源文件需要依赖src下的源码,所以src写在前面
SUBDIRS = \
    src \
    test \
    $(NULL)

5、子目录下的Makefile.am文件

1)src目录下的Makefile.am文件(这个文件是本篇文章想表达的重点

#表示最终要生成库文件 .a .so
lib_LTLIBRARIES = libshow-notify.la

# $(includdir)的值由autoconf为我们自动生成,默认是'/urs/include' or '/usr/local/include'
libshow_notify_la_CPPFLAGS = \
    -I$(includedir) \
    $(GLIB2_CFLAGS) \
    $(LIBNOTIFY_CFLAGS) \
    $(NULL)

#未研究这个,读者可自行研究
#libshow_notify_la_LDFLAGS=\
#   --no-undefined \
#   $(NULL)

libshow_notify_la_LIBADD = \
    $(GLIB2_LIBS) \
    $(LIBNOTIFY_LIBS) \
    $(NULL)

#指定make install要安装的头文件具体路径
#在生成的Makefile文件中,会自动加上$(DESTDIR)前缀
libshow_notify_includedir=$(includedir)
#指定make install要安装哪些头文件
libshow_notify_include_HEADERS = \
    show-notify.h \
    $(NULL)

libshow_notify_la_SOURCES = \
    show-notify.h \
    show-notify.c \
    $(NULL)

# 开启对DESTDIR的定义后,执行make install会将库、.h 文件安装到项目目录下 $(abs_top_srcdir)/usr/local/
# 若不开启,sudo make install可以将库、.h文件安装到系统目录下/usr/local/
#DESTDIR = $(abs_top_srcdir)

2)test目录下的Makefile.am文件

#注意 = 后面没有空格
NULL =

#表示要生成一个可执行二进制程序
bin_PROGRAMS = \
    test-show-notify \
    $(NULL)

# _CPPFLAGS指定gcc预处理阶段头文件的查找路径(gcc -I)
test_show_notify_CPPFLAGS = \
    -I$(top_srcdir)/src \
    $(NULL)

# _LDADD指定gcc链接阶段要链接的库文件(gcc -l)
test_show_notify_LDADD = \
    $(top_srcdir)/src/libshow-notify.la \
    $(NULL)

#生成二进制要依赖的源码文件
test_show_notify_SOURCES = \
    main.c \
    $(NULL)

#读者可对比开启下面定义后,运行make install会有哪些差异
#DESTDIR = $(abs_top_srcdir)

6、细节点播:

读者可以自行对比这个案例中test目录下生成的可执行文件与之前2个案例生成的可执行文件(使用file命令检测):
1)之前2个目录生成的可执行文件是ELF二进制文件(vim打开时乱码);该案例test目录下可执行文件是个shell脚本。

2)关于该案例中可执行文件运行的问题:

  • test目录下shell脚本可以运行且生效。

  • 定义DESTDIR=$(abs_top_srcdir)后,make install安装到项目根目录,运行./usr/local/bin/test-show-nofity会报错:libshow-notidy.so.0找不到

  • 不定义DESTDIR,sudo make install默认安装到系统目录,/usr/local/bin/test-show-nofity可以成功运行且生效。

    原因解析:

    1. shell脚本会根据脚本中的内容在当前目录 .deps .libs 目录下查找依赖
    2. 运行ELF文件默认会从系统目录下寻找依赖的libshow-notify.so文件,如果系统目录下不存在该文件,则运行失败,这是install到项目根目录下和系统目录下的区别。(使用ldd命令查看ELF文件依赖的库)

你可能感兴趣的:(linux)