我的库是在启用了一些#define
(例如-DUSE_FOO=1
)的基础上构建的,并且USE_FOO
也在公共头文件中使用。问题是使用库的应用程序包含公共头文件,因此USE_FOO
出现在应用程序上下文中,并且在应用程序上下文中将是未定义的。
如何根据是否在库中启用USE_FOO
定义到应用程序?
e.g
include/public/foo.h
lib/libfoo.so --> foo.cc
in foo.h contain code as
#if defined (USE_FOO)
#define SIZE 5
#else
#define SIZE 10
#endif
foo.cc
#include "foo.h"
int getSizeFromLib()
{
return SIZE;
}
libfoo.so
源文件包含foo.h
,并通过在编译时配置USE_FOO
构建。
现在,应用程序通过包含public/foo.h
使用libfoo库并使用他自己的构建配置来构建应用程序。但问题是应用程序不知道USE_FOO
,它在应用程序端总是未定义的。所以SIZE
将在申请中获得10分,但在图书馆内将有5分
我希望USE_FOO
根据是否为libfoo.so
定义导出到应用程序。即如果libfoo.so
是用USE_FOO=1
应用构建的,也应该看USE_FOO=1
,反之亦然
如果不可能以预先定义的方式进行,那么任何解决这个问题的技巧都会受到欢迎。
在Linux世界中,这个任务由pkgconfig工具解决。基本上除了二进制文件和标题之外,你的库还附带一个.pc
文件,看起来像
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: foo
Description: The foo library
Version: 1.0.0
Cflags: -I${includedir}/foo USE_FOO=1
Libs: -L${libdir} -lfoo
此文件安装到/usr/lib/pkgconfig
,客户端应通过从Makefile调用CFLAGS
从中查询正确的pkg-config
:
CFLAGS = -g -Wall -Wextra $(pkg-config --cflags)
有关更多详细信息,请查看guide。
唯一可移植的解决方案是添加一个自动生成的foo-config.h
标头,该标头将包含在所有库公共标头中,并定义所有特定于版本的定义(如USE_FOO
)。这当然只适用于实际包含库头的源文件。
无法将预处理器定义从库“导出”到应用程序。两者都必须使用兼容标志进行编译,例如:
CFLAGS=-DUSE_FOO=1
gcc $CFLAGS --shared -o lib/libfoo.so foo.cc
gcc $CFLAGS lib/libfoo.so app.c