我正在尝试将静态库的某些部分链接到 Linux 下使用 g++ 用 C++ 编写的程序中。
my_lib.h
#ifdef USE_EXTERN_LIB
# include <extern_lib.h>
void do_something (struct extern_lib);
#endif
void do_other (int);
Run Code Online (Sandbox Code Playgroud)
my_lib.c
#include "my_lib.h"
#ifdef USE_EXTERN_LIB
void do_something (struct extern_lib l)
{
// do something
}
#endif
void do_other (int a)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
我使用 -DUSE_EXTERN_LIB 预处理器标志静态创建 libmy_lib.a 以将所有内容包含到其中。
但我想做的是创建两个程序:一个将这个库与 *extern_lib* 一起使用,另一个在不使用 *extern_lib* 的情况下使用它,即:
g++ -L/path/to/lib -lmy_lib -o prog_wihtout_lib prog_without_lib.cc
g++ -DUSE_EXTERN_LIB -L/path/to/lib -lmy_lib -o prog_with_lib prog_with_lib.cc
Run Code Online (Sandbox Code Playgroud)
第二个程序可以编译,但第一个程序不能编译,它说 extern_lib 未声明。
使用动态库,没有问题,因为符号是在运行时加载的,但我想要一个静态库。有没有办法只链接静态库所需的模块?
编辑
prog_without_lib.cc
#include "my_lib.h"
int main ()
{
do_other (42);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
prog_with_lib.cc
#include "my_lib.h"
int main ()
{
do_other (42);
struct extern_lib l;
do_something (l);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
只需链接到库中,然后让链接器负责删除未使用的代码。这就是它的工作。
您尝试做的事情没有任何意义(不,它在动态库中也没有任何意义。)定义仅在您编译库时才有效,并且您在第一行执行此操作。在第二行,您只需将已编译的库链接到可执行文件中。但实际上,静态库的全部要点是它们对链接器是可见的,因此它可以(除其他外)删除任何未使用的代码。那么为什么你需要USE_EXTERN_LIB 定义呢?
在第二个命令行中构建时,必须将外部库添加到命令行:
g++ -DUSE_EXTERN_LIB -I/path/to/external_lib/headers -o prog_wih_lib prog_with_lib.cc -L/path/to/external_lib/libfile -lexternal_lib -lmy_lib
Run Code Online (Sandbox Code Playgroud)
另请注意,我将库放在命令行的末尾。可能不再需要了,但过去链接器按照命令行上给出的顺序扫描输入文件,因此如果在对象文件使用它之前库位于命令行上,则链接器会退出错误提示无法找到符号。