Apache APR 配置与构建参数详解

逐参数实测详解 APR 构建配置体系:apr-1-config/apu-1-config 全部选项的真实输出、configure 关键选项(crypto/ldap/dbd/dbm 等)的探测行为与缺依赖回退、安装目录结构与编译链接模板,基于 Ubuntu 22.04 与 CentOS 8 双环境实测。

Apache APRApache APRC/C++命令行Linux2026/10/16

Apache APR 配置与构建参数详解

目标:把 APR 的两类「配置」一次讲透——下游程序编译链接用的 apr-1-config/apu-1-config 全参数,与构建 APR 自身的 ./configure 关键选项(crypto/LDAP/DBD/DBM 等);每个参数都给出实测输出与行为解读,基于 apr 1.7.6 + apr-util 1.6.5 在 Ubuntu 22.04 与 CentOS 8 双环境实测。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64,GCC 11.4.0)为主、CentOS 8(x86_64,GCC 8.5.0)对照;
  • 软件版本:apr 1.7.6、apr-util 1.6.5(源码编译,前缀 /usr/local/apr);
  • 本文所有 apr-1-config/apu-1-config 输出均为在 /usr/local/apr/bin/ 下实测采集,个别标注 CentOS 差异处另注明;
  • 专栏内安装过程见《Apache APR 在 Ubuntu 22.04 集成使用指南》,本文聚焦参数体系。

二、前置条件

  • 已按集成指南完成 apr/apr-util 源码编译安装(或 apt/yum 仓库安装,注意工具路径为 /usr/bin/apr-1-config);
  • 验证工具可用:
$ /usr/local/apr/bin/apr-1-config --version
1.7.6
$ /usr/local/apr/bin/apu-1-config --version
1.6.5
  • 建议同时安装 pkg-config(Ubuntu:apt-get install -y pkg-config),APR 安装后自带 .pc 文件,可作为 apr-1-config 的等价通道(见 8.1)。

三、参数查看与修改方式

APR 的「配置」分两个层面,修改方式完全不同,先建立全局认识:

层面载体查看方式修改方式
构建期(编 APR 自身)./configure 选项源码树 ./configure --help重新 configure + make install
使用期(下游程序取参)apr-1-config / apu-1-config 脚本逐参数执行只读不可改(值在安装时固化)

apr-1-config 本体是一个 shell 脚本,安装时把 configure 的探测结果(编译器、宏、库路径)以字面量写进脚本,因此「运行期改参数」是不存在的——想改输出只能重编。这一点有一个实测佐证:--prefix=DIR 参数在帮助里写着「change prefix to DIR」,但对已安装脚本执行后输出不变(实测):

$ /usr/local/apr/bin/apr-1-config --prefix=/opt/myapr --includedir --link-ld
/usr/local/apr/include/apr-1
 -L/usr/local/apr/lib -lapr-1

(--prefix=/opt/myapr 并未让 includedir/link-ld 跟着变,输出仍是安装时固化的 /usr/local/apr。)

两个工具的完整帮助(实测全文):

$ /usr/local/apr/bin/apr-1-config --help
Usage: apr-1-config [OPTION]

Known values for OPTION are:
  --prefix[=DIR]    change prefix to DIR
  --bindir          print location where binaries are installed
  --includedir      print location where headers are installed
  --cc              print C compiler name
  --cpp             print C preprocessor name and any required options
  --cflags          print C compiler flags
  --cppflags        print C preprocessor flags
  --includes        print include information
  --ldflags         print linker flags
  --libs            print additional libraries to link against
  --srcdir          print APR source directory
  --installbuilddir print APR build helper directory
  --link-ld         print link switch(es) for linking to APR
  --link-libtool    print the libtool inputs for linking to APR
  --shlib-path-var  print the name of the shared library path env var
  --apr-la-file     print the path to the .la file, if available
  --apr-so-ext      print the extensions of shared objects on this platform
  --apr-lib-target  print the libtool target information
  --apr-libtool     print the path to APR's libtool
  --version         print the APR's version as a dotted triple
  --help            print this help

When linking with libtool, an application should do something like:
  APR_LIBS="`apr-1-config --link-libtool --libs`"
or when linking directly:
  APR_LIBS="`apr-1-config --link-ld --libs`"

An application should use the results of --cflags, --cppflags, --includes,
and --ldflags in their build process.

(apu-1-config 的 --help 全文见第五章。)

四、apr-1-config 全参数详解

以下 20 个参数全部逐个实测(apr 1.7.6,Ubuntu 22.04 源码安装,前缀 /usr/local/apr)。命令与回显一一对应:

$ A=/usr/local/apr/bin/apr-1-config
$ $A --bindir
/usr/local/apr/bin
$ $A --includedir
/usr/local/apr/include/apr-1
$ $A --cc
gcc
$ $A --cpp
gcc -E
$ $A --cflags
 -g -O2
$ $A --cppflags
 -DLINUX -D_REENTRANT -D_GNU_SOURCE
$ $A --includes
 -I/usr/local/apr/include/apr-1
$ $A --ldflags
(空输出)
$ $A --libs
 -luuid -lcrypt  -lpthread
$ $A --srcdir
/root/src/apr-1.7.6
$ $A --installbuilddir
/usr/local/apr/build-1
$ $A --link-ld
 -L/usr/local/apr/lib -lapr-1
$ $A --link-libtool
 /usr/local/apr/lib/libapr-1.la
$ $A --shlib-path-var
LD_LIBRARY_PATH
$ $A --apr-la-file
 /usr/local/apr/lib/libapr-1.la
$ $A --apr-so-ext
lo
$ $A --apr-lib-target
-rpath $(libdir) $(OBJECTS)
$ $A --apr-libtool
/usr/local/apr/build-1/libtool
$ $A --version
1.7.6
$ $A --prefix
/usr/local/apr

逐参数解读(按用途分组):

目录定位类:--prefix(安装前缀)、--bindir(可执行目录)、--includedir(头文件目录)、--installbuilddir(构建辅助规则目录,供 httpd 等上游复用 APR 的编译规则)、--srcdir(编译时源码树路径——注意它指向 configure 当时的源码目录,源码树删除后该参数输出仍在)。

编译参数类:--cc/--cpp(编译器与预处理器)、--cflags(优化级别 -g -O2,configure 时决定)、--cppflags(三个平台宏:LINUX/REENTRANT/GNU_SOURCE,必须在编译命令中带上)、--includes(头文件搜索路径)。

链接参数类:--libs(APR 自身依赖的系统库——注意不含 -lapr-1 本体)、--link-ld(库搜索路径 + -lapr-1,直接链接用这个)、--link-libtool(给 libtool 构建系统用,指向 .la 文件)、--ldflags(本环境为空)、--apr-la-file(.la 路径)、--shlib-path-var(动态库环境变量名,Linux 为 LD_LIBRARY_PATH)。

libtool 内部类:--apr-so-ext(libtool 对象后缀 lo)、--apr-lib-target(libtool 目标模板)、--apr-libtool(APR 自带的 libtool 副本路径)。这三个只服务于把 APR 嵌入更大构建系统的场景(如 httpd),普通应用用不到。

CentOS 8 同版本对照差异(实测):--cflags --cppflags --includes 组合输出为 -g -O2 -pthread -DLINUX -D_REENTRANT -D_GNU_SOURCE -I/usr/local/apr/include/apr-1(多 -pthread);--libs 为 -luuid -lrt -lcrypt -lpthread -ldl(多 -lrt -ldl)。差异源于两发行版 glibc 对 clock_gettime 等函数的库拆分不同,configure 自动探测吸收,下游无需处理。

⚠️ 注意:多参数可组合使用,输出按顺序拼接(实测 --libs --link-ld 输出 -luuid -lcrypt -lpthread -L/usr/local/apr/lib -lapr-1)。官方推荐的两种组合模板就在 --help 尾部:libtool 构建用 --link-libtool --libs,直接链接用 --link-ld --libs。

五、apu-1-config 全参数详解

apu-1-config 帮助全文(实测):

$ /usr/local/apr/bin/apu-1-config --help
Usage: apu-1-config [OPTION]

Known values for OPTION are:
  --prefix[=DIR]    change prefix to DIR
  --bindir          print location where binaries are installed
  --includes        print include information
  --includedir      print location where headers are installed
  --ldflags         print linker flags
  --libs            print library information
  --avoid-ldap      do not include ldap library information with --libs
  --ldap-libs       print library information to link with ldap
  --avoid-dbm       do not include DBM library information with --libs
  --dbm-libs        print additional library information to link with DBM
  --srcdir          print APR-util source directory
  --link-ld         print link switch(es) for linking to APR-util
  --link-libtool    print the libtool inputs for linking to APR-util
  --apu-la-file     print the path to the .la file, if available
  --old-expat       indicate if APR-util was built against an old expat
  --db-version      print the DB version
  --version         print APR-util's version as a dotted triple
  --help            print this help

When linking with libtool, an application should do something like:
  APU_LIBS="`apu-1-config --link-libtool --libs`"
or when linking directly:
  APU_LIBS="`apu-1-config --link-ld --libs`"

An application should use the results of --includes, and --ldflags in
their build process.

逐参数实测(初始为 sdbm-only 构建,后启用全部可选组件,两轮输出都给出):

$ A=/usr/local/apr/bin/apu-1-config
$ $A --bindir
/usr/local/apr/bin
$ $A --includedir
/usr/local/apr/include/apr-1
$ $A --includes
 -I/usr/local/apr/include/apr-1 -I/usr/include
$ $A --ldflags
 -L/usr/lib -L/usr/lib64
$ $A --libs
     -lexpat
$ $A --srcdir
/root/src/apr-util-1.6.5
$ $A --link-ld
 -L/usr/local/apr/lib -laprutil-1
$ $A --link-libtool
 /usr/local/apr/lib/libaprutil-1.la
$ $A --apu-la-file
 /usr/local/apr/lib/libaprutil-1.la
$ $A --old-expat
@APR_XML_EXPAT_OLD@
$ $A --db-version
0
$ $A --version
1.6.5
$ $A --prefix
/usr/local/apr
$ $A --ldap-libs
(空输出)
$ $A --dbm-libs
(空输出)

逐项解读:

  • --libs:apr-util 自身依赖(默认只有 -lexpat,XML 解析库)。启用 LDAP/BDB 后变为 -lldap -llber -ldb-5.3 -lexpat(实测重编后输出);
  • --ldap-libs/--dbm-libs:分别输出 LDAP、DBM 后端的链接库。初始未启用时为空;启用后分别输出 -lldap -llber 与 -ldb-5.3;
  • --avoid-ldap/--avoid-dbm:开关式参数,让后续 --libs 输出剔除对应库信息(输出为空行,属正常);
  • --db-version:DBM 后端主版本号。实测关键差异:sdbm-only 构建输出 0(内置库无版本),启用 Berkeley DB 5.3 重编后输出 5;
  • --old-expat:本应输出 0/1 指示是否链接老版 expat;实测输出未替换的模板串 @APR_XML_EXPAT_OLD@——apr-util 1.6.5 的已知瑕疵,忽略即可(判断 expat 用 --libs 里是否有 -lexpat 更可靠)。

CentOS 8 仓库版对照(实测):/usr/bin/apu-1-config --libs 输出 -lldap_r -llber -ldb-5.3 -lexpat——发行版把线程安全 LDAP(ldap_r)与 BDB 编进了 apr-util 主包,与源码自编按需启用不同。

六、configure 关键选项详解

6.1 apr 核心库的常用选项

apr 1.7.6 的 configure 支持约 40 个选项(./configure --help 可查全量)。生产构建最值得关注的实测清单:

选项默认说明与实测行为
--prefix=DIR/usr/local/apr安装前缀,本文实测 /usr/local/apr
--enable-threads启用线程支持;实测默认开(apr_thread_demo 4 线程运行正常)
--enable-nonportable-atomics关用平台特化原子指令提速,产物不可跨 CPU 移植;单用途服务器可开
--enable-pool-debug[=MODE]关内存池调试(verbose/lifetime 等模式),定位池误用
--enable-maintainer-mode关调试编译(-g 级别警告全开)
--disable-dso启用 DSO关闭动态库加载支持(apr_dso),极少用
--disable-ipv6启用 IPv6关闭 IPv6 支持
--disable-lfs启用 LFS关闭大文件支持(32 位平台相关)
--with-devrandom=DEV自动搜索指定随机源设备(/dev/random 或 /dev/urandom)
--with-sendfile自动强制启用/禁用 sendfile 零拷贝发送

apr 侧没有 --with-* 外部依赖(全部能力内核原生提供),这是它与 apr-util 的结构性区别。

6.2 apr-util 的依赖选项与探测行为

apr-util 的可选组件全部通过 --with-* 开启,全量选项表(configure --help 实测摘录):

选项启用的能力依赖包(Ubuntu)
--with-apr=PATH(必需)指定 apr-1-config 路径已装 apr
--with-crypto加密框架总开关无(配合 openssl/nss)
--with-openssl=DIRopenssl 加密驱动libssl-dev
--with-nss=DIRNSS 加密驱动libnss3-dev
--with-ldap[=library]LDAP 支持(apr_ldap)libldap2-dev
--with-gdbm=DIRGDBM 后端libgdbm-dev
--with-ndbm=PATHNDBM 后端系统 ndbm
--with-berkeley-db=PATHBerkeley DB 后端libdb-dev
--with-pgsql=DIRPostgreSQL DBD 驱动libpq-dev
--with-mysql=DIRMySQL/MariaDB DBD 驱动libmariadb-dev
--with-sqlite3=DIRSQLite3 DBD 驱动libsqlite3-dev
--with-odbc=DIRODBC DBD 驱动unixodbc-dev
--with-expat=DIR指定 expat 位置(默认系统库)libexpat1-dev
--disable-util-dso(默认启用 DSO)改为主库内置重组件—

缺依赖时的探测行为(重要,实测):未安装 libldap2-dev 时直接传 --with-ldap,configure 不会报错退出,而是把各厂商 LDAP 库逐个探测一遍全部失败后静默回退为「无 LDAP」:

$ ./configure --prefix=/usr/local/apr --with-apr=/usr/local/apr/bin/apr-1-config --with-ldap
checking for ldap support...
checking for ldap_init in -lldap50... no
checking for ldap_init in -lldapssl41... no
checking for ldap_init in -lldapssl40... no
checking for ldap_init in -lldapssl30... no
checking for ldap_init in -lldapssl20... no
checking for ldap_init in -lldapsdk... no
checking for ldap_init in -lldap... no
(configure 退出码 0)

装齐依赖后重新 configure,探测立即命中并打印链接变量(实测):

checking for ldap_init in -lldap... yes
checking for ldap_start_tls_s in -lldap... yes
  setting LDADD_ldap to "-lldap -llber"
  setting LDADD_dbm_db to "-ldb-5.3"
  setting LDADD_dbd_mysql to "-L/usr/lib/x86_64  -lmariadb -L/usr/lib/x86_64-linux-gnu/ -lmariadb"
  setting LDADD_dbd_sqlite3 to " -lsqlite3"

⚠️ 注意:判断某组件是否真的启用,看 configure 输出里的 setting LDADD_xxx to ... 行,而不是「configure 没报错」。这是 APR 构建里最容易踩的坑:--with-ldap + 缺依赖 = 静默无 LDAP。

全量启用后的连带变化(实测):重编安装后 apu-1-config --libs 由 -lexpat 变为 -lldap -llber -ldb-5.3 -lexpat,--db-version 由 0 变 5,/usr/local/apr/lib/apr-util-1/ 下生成 5 个 DSO 模块(apr_crypto_openssl、apr_dbd_mysql、apr_dbd_sqlite3、apr_dbm_db、apr_ldap 各 -1.so)。

6.3 生产构建参数模板

按场景给出推荐的 configure 组合(以下为参数模板,实际编译步骤见集成指南):

  • 最小依赖(纯核心功能):./configure --prefix=/usr/local/apr(apr);./configure --prefix=/usr/local/apr --with-apr=...(apr-util,仅 expat/sdbm);
  • Web 服务端(httpd 前置):apr-util 加 --with-crypto --with-openssl=/usr --with-ldap(httpd 的 mod_session_crypto/ mod_authnz_ldap 需要);
  • 数据库网关类应用:apr-util 加 --with-sqlite3 --with-mysql --with-pgsql(DBD 驱动按需选装);
  • 性能敏感型:apr 加 --enable-nonportable-atomics(绑定 CPU 架构换取原子操作提速)。

七、安装目录结构详解

源码安装(前缀 /usr/local/apr)后的完整布局(Ubuntu 实测,CentOS 一致):

目录/文件内容实测证据
bin/apr-1-config、apu-1-config 两个脚本ls /usr/local/apr/bin/ 输出 2 个文件
include/apr-1/72 个头文件(apr 核心约 50 + apu 扩展 20+)`ls /usr/local/apr/include/apr-1/apr*.h
lib/libapr-1.so.0.7.6、libaprutil-1.so.0.6.5(含 .a/.la 与软链)、apr.exp/aprutil.exp见 3.2 节实测 ls 输出
lib/apr-util-1/DSO 模块目录(crypto/dbd/dbm/ldap 驱动)启用组件后含 5 个 -1.so
lib/pkgconfig/apr-1.pc、apr-util-1.pcpkg-config 通道(见 8.1)
build-1/apr_rules.mk、libtool 副本等构建辅助--installbuilddir 指向此处

安装总体积实测约 7.4MB(CentOS du -sh /usr/local/apr 输出 7.4M /usr/local/apr)。发行版 rpm 布局差异:CentOS 8 仓库版头文件在 /usr/include/apr-1/(76 个,比源码版多出的是 rpm 拆包子包携带的可选头)、DSO 模块在 /usr/lib64/apr-util-1/(实测仅含已安装 sub-package 对应的 apr_crypto_openssl-1.so 与 apr_dbm_db-1.so)。

八、编译链接组合实战

8.1 三种取参通道

同一份编译参数有三个获取通道,按构建系统选择(输出内容等价,实测):

# 通道一:apr-1-config(经典)
$ gcc app.c $(apr-1-config --cflags --cppflags --includes) $(apr-1-config --link-ld --libs)

# 通道二:pkg-config(现代构建系统 / CMake)
$ PKG_CONFIG_PATH=/usr/local/apr/lib/pkgconfig pkg-config --cflags --libs apr-1
-DLINUX -D_REENTRANT -D_GNU_SOURCE -g -O2 -I/usr/local/apr/include/apr-1 -L/usr/local/apr/lib -lapr-1 -luuid -lcrypt -lpthread
$ PKG_CONFIG_PATH=/usr/local/apr/lib/pkgconfig pkg-config --modversion apr-util-1
1.6.5

# 通道三:libtool 构建系统(httpd 模块开发)
$ gcc app.c $(apr-1-config --link-libtool --libs)

💡 说明:pkg-config 通道读的是安装时生成的 .pc 文件;自建前缀必须用 PKG_CONFIG_PATH 指到 /usr/local/apr/lib/pkgconfig,系统默认搜索不到。apr-util 的 .pc 文件已声明对 apr-1 的依赖,pkg-config --cflags --libs apr-util-1 一条即同时带上两个库(实测输出含 -laprutil-1 -lapr-1 与各自依赖)。

8.2 双库全链接模板

同时使用 apr 与 apr-util(如 crypto/DBD 场景)的完整编译命令(实测编译通过):

$ APR=/usr/local/apr/bin/apr-1-config
$ APU=/usr/local/apr/bin/apu-1-config
$ gcc app.c $($APR --cflags --includes) $($APU --includes) \
      $($APR --link-ld) $($APU --link-ld) $($APU --libs) $($APR --libs)

参数含义:cflags/cppflags 从 apr 取(apr-util 的 cflags 与之一致);include 两边都给(apu 头文件与 apr 同目录但多一个 -I/usr/include);链接顺序 apu 在前 apr 在后(依赖方向)。运行期需保证 /usr/local/apr/lib 在 ld 缓存中(见集成指南 5.4)。

九、常见问题(FAQ)

Q1:--prefix=DIR 传了新路径为什么输出没变? apr-1-config 是安装时固化的脚本,--prefix[=DIR] 只在源码树内的 apr-config 模板上有意义(配合 make install 阶段替换)。已安装脚本上传该参数不改变任何输出(本文第三章实测佐证)。要改前缀请重新 configure。

Q2:--old-expat 输出 @APR_XML_EXPAT_OLD@ 是坏了吗? 是 apr-util 1.6.5 的模板替换瑕疵(实测输出原样保留占位符)。判断 expat 版本请改用 apu-1-config --libs 是否含 -lexpat。

Q3:--with-ldap 没报错但程序里 apr_ldap 头文件功能缺失? 缺 libldap2-dev 时 configure 静默回退(6.2 节实测的逐库探测全 no)。补依赖重编后,用 apu-1-config --ldap-libs 验证:输出 -lldap -llber 才是真的启用了。

Q4:--db-version 输出 0 是什么意思? 0 表示 DBM 后端是内置 sdbm(无外部版本号);启用 Berkeley DB 后输出主版本(实测 BDB 5.3 → 输出 5)。该参数用于运行期判断 DBM 文件兼容性。

Q5:CentOS 与 Ubuntu 上 apr-1-config 输出不一致,代码要写两套吗? 不要。两个发行版的差异(-pthread、-lrt -ldl 有无)都在 config 工具输出里自动吸收,构建脚本永远引用 $($APR --cflags ...) 等占位即可,跨发行版零改动(本文双环境实测同一编译命令均通过)。

十、参考链接