栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux 编写configure.ac和Makefile.am示例

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux 编写configure.ac和Makefile.am示例

前面说的

我们知道configure.ac可以生成configure文件,而Makefile.am可以生成Makefile.am,之所以这么做就是为了适应不同的环境需求

我已经写好了一个示例,目录结构如下

# tree
.
├── a.c
├── b.c
├── b.h
├── configure.ac
├── Makefile.am
└── src
    ├── c.c
    ├── c.h
    ├── d.c
    ├── d.h
    └── Makefile.am

我想在src的文件夹编译一个静态库,叫libfoo.a,基于c.c、d.c、c.h、d.h生成

我想用a.c编译一个程序叫做test,并引用了上面的 libfoo.a

代码

c文件代码(不是很重要)

// a.c
#include 
#include "b.h"
#include "src/c.h"
void main()
{
    fun1();
    fun2();
}

// b.c
#include 
int fun1()
{
   return 1;
}

// b.h
#include 
int fun2()
{
   return 1;
}

// c.c
#include 
int fun2()
{
   return 1;
}

// c.h
#include 
int fun2();

// d.c
#include 
int fun3()
{
   return 1;
}

// d.h
#include 
int fun3()
{
   return 1;
}

configure.ac

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

AC_PREREQ([2.69])
AC_INIT([myproject], [1.0.0])
AC_CONFIG_SRCDIR([a.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
AM_PROG_AR

# Checks for libraries.
AC_CHECK_LIB([curl], [curl_easy_perform], [CURL123=-lcurl], AC_MSG_ERROR("需要安装curl库"))
AC_SUBST([CURL123])

# Checks for header files.
have_openssl=yes
AC_CHECK_HEADER(openssl/sha.h, [have_openssl=yes], [have_openssl=no])

if test "x$have_openssl" != "xyes"
then
AC_MSG_ERROR("需要安装openssl库")
else
AC_MSG_WARN("else示范")
fi

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

Makefile.am (外层)

AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4

bin_PROGRAMS = test
test_SOURCES = a.c b.c
noinst_HEADERS = b.h src/c.h
test_LDADD = @CURL123@ src/libfoo.a

SUBDIRS = src/
#AM_CFLAGS = -L/usr/include

src/Makefile.am

lib_LIBRARIES = libfoo.a
libfoo_a_SOURCES = c.c d.c
include_HEADERS = c.h d.h
前提

假设大家已经安装了 automake make gcc 等软件

正文 configure.ac

先来说是configure.ac文件

configure.ac 文件可以由 autoscan命令生成,autoscan会生成一个log文件(不用管)和一个configure.scan,修改configure.scan的名称为configure.ac

configure.scan内容如下

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

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([a.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

然后看到我修改后的文件(configure.ac 见文章开头,后面的Makefile.am也是如此)

按照先后顺序,讲讲上面的宏,不建议跳着看,宏和左括号之间不要有空格,容易发生意想不到的错误

AC_PREREQ

autoconf的版本号,基本不用修改

AC_INIT

可以带三个参数,分别是项目名称,版本号,邮箱,可以不填邮箱

AC_CONFIG_HEADERS([config.h])

先说这个,这个文件里面包含了上面写的版本号,项目名称等信息,以及某些头文件是否存在的宏定义,小工程可能用不上这些,大的开源项目需要包含这个文件,做一些宏的判断操作

AC_CONFIG_SRCDIR

检测文件是否存在,一般检测的是主文件,但个人感觉没啥用,这个宏如果定义了,后面的文件一定要存在,不然可能报错

configure: error: cannot find install-sh, install.sh, or shtool in ".." "../.." "../../.."
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

automake的编译选项,一般没啥变化

AC_PROG_CC

gcc编译器,后面可以加编译器名称,用于其他平台编译

AC_PROG_CXX

g++编译器,不加编译不了cpp

AC_PROG_RANLIB AM_PROG_AR

这两个宏用于编译库文件,这次的示例有编译静态库用到

AC_CHECK_LIB

检查库文件是否存在 (可选宏)

AC_CHECK_LIB([curl], [curl_easy_perform], [CURL123=-lcurl], AC_MSG_ERROR("需要安装curl库"))

这个表示,我要检查curl库是否存在,我将尝试curl_easy_perform(curl库的函数),如果存在我设置一个宏 CURL123 (后面Makefile.am用到),CURL123即 -lcurl,如果不存在则弹出报错提示  "需要安装curl库"

AC_SUBST

跟上面的CURL123宏配合使用,用于Makefile.am

AC_MSG_ERROR

报错并中断编译,宏后面可以接上报错提示

AC_MSG_WARN

报错但不中断编译,宏后面可以接上报错提示

AC_CHECK_HEADER

(可选宏)第一个参数检查头文件是否存在,后面两个参数(可选)分别是,如果头文件存在则做什么(可以不填东西,比如 , , 代替),如果头文件不存在做什么

AC_CONFIG_FILES

一般指定Makefile.am的位置

AC_OUTPUT

configure.ac结束标志


Makefile.am 文件

Makefile.am (外层) AUTOMAKE_OPTIONS   ACLOCAL_AMFLAGS

这两个宏貌似加不加都不影响编译

bin_PROGRAMS

指定编译的程序名称,比如我指定程序叫做test,影响我后面选项的构成,后面跟test名称相关,基本都是我这里指定的,可以指定多个

test_SOURCES

严格来说这个不算一个标准宏 是  程序名称加下划线SOURCES,主要是指定你的程序依赖的 .c 文件,可以指定多个,可以带路径,如果我们c文件过多,我们可以使用 ls *.c 快速过滤文件

noinst_HEADERS

noinst代表不需要安装,我做的示例不是给别人用的开发库,没必要安装到系统目录下。

可以指定多个头文件,可以带路径,一般不用带路径,如果你想引用上层目录的commom文件夹的xxx.h文件,只需要在当前目录的头文件写 #include "commom/xxx.h",子模块这么写include是表示上一级目录,父模块这么写表示下一级目录

test_LDADD

指定程序依赖的库可以直接写如 -lcurl,而我这里跟前面configure.ac联动,动态指定 -lcurl

SUBDIRS

子目录,优先编译子目录的内容,比如我那个 .a 库,再编译当前内容

AM_CFLAGS

gcc编译选项(我加#号注释了),Makefile直接指定CFLAGS,而Makefile.am指定编译选项需要加个AM_前缀

AM_CXXFLAGS

g++编译选项,g++的选项加在 AM_CFLAGS 则无效,如 -std=c++11

src/Makefile.am lib_LIBRARIES

编译的库名,记住要用lib作为库名开头,不然会报错说你不是标准名称,我这里指定叫做 libfoo.a,同样影响后面

libfoo_a_SOURCES

像点这种特殊符号就用下划线代填

include_HEADERS

包含的头文件路径,可以用 noinst_HEADERS 代填,这里主要是用于示范,应该会安装

编译库这里踩过一个大坑,我看到有的教程把 lib_LIBRARIES 写成 lib_LTLIBRARIES,然后我疯狂报错

src/Makefile.am:1: error: Libtool library used but 'LIBTOOL' is undefined
src/Makefile.am:1:   The usual way to define 'LIBTOOL' is to add 'LT_INIT'
src/Makefile.am:1:   to 'configure.ac' and run 'aclocal' and 'autoconf' again.
src/Makefile.am:1:   If 'LT_INIT' is in 'configure.ac', make sure
src/Makefile.am:1:   its definition is in aclocal's search path.

像这种不存在的宏,它不会识别,直接认为Makefile.am是一个空文件,说我没写 configure.ac 服了

文件都写好了就开始正式编译了,编译命令如下,教程结束

# 下面这四步可以生成configure文件,不深究为啥是这样
aclocal
autoheader
autoconf
automake --add-missing

# 下面是正常的编译流程
./configure
make clean
make

参考资料

总览

configure.ac和Makefile.am的格式解析概述 - never715 - 博客园

【Linux】自动生成makefile(ubuntu)_棱角为零的博客-CSDN博客_自动生成makefile

configure.ac

编写configure.ac_john_crash的博客-CSDN博客_ac_config_srcdir

Makefile.am

编写Makefile.am_john_crash的博客-CSDN博客

Makefile.am 解释_iteye_15968的博客-CSDN博客

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1015580.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号