链接到可执行文件时如何强制将目标文件包含在静态库中? [英] How to force inclusion of an object file in a static library when linking into executable?

查看:18
本文介绍了链接到可执行文件时如何强制将目标文件包含在静态库中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 C++ 项目,由于其目录结构被设置为静态库 A,它被链接到共享库 B,它被链接到可执行文件C.(这是一个使用 CMake 的跨平台项目,所以在 Windows 上我们得到 A.libB.dllC.exe,在 Linux 上,我们得到 libA.alibB.soC.)库 A 有一个 init函数(A_init,在A/initA.cpp中定义),从库B的init函数(B_init,定义在 B/initB.cpp),从 C 的 main 中调用.因此,当链接 B 时,A_init(以及在 initA.cpp 中定义的所有符号)被链接到 B(这是我们想要的行为).

I have a C++ project that due to its directory structure is set up as a static library A, which is linked into shared library B, which is linked into executable C. (This is a cross-platform project using CMake, so on Windows we get A.lib, B.dll, and C.exe, and on Linux we get libA.a, libB.so, and C.) Library A has an init function (A_init, defined in A/initA.cpp), that is called from library B's init function (B_init, defined in B/initB.cpp), which is called from C's main. Thus, when linking B, A_init (and all symbols defined in initA.cpp) is linked into B (which is our desired behavior).

问题在于 A 库还定义了一个预期的函数(Af,在 A/Afort.f 中定义)通过动态加载(即 Windows 上的 LoadLibrary/GetProcAddress 和 Linux 上的 dlopen/dlsym).由于库 B 中没有对 Af 的引用,因此 A/Afort.o 中的符号不​​包含在 B.在 Windows 上,我们可以使用 pragma 人为地创建引用:

The problem comes in that the A library also defines a function (Af, defined in A/Afort.f) that is intended to by dynamically loaded (i.e. LoadLibrary/GetProcAddress on Windows and dlopen/dlsym on Linux). Since there are no references to Af from library B, symbols from A/Afort.o are not included into B. On Windows, we can artifically create a reference by using the pragma:

#pragma comment (linker, "/export:_Af")

由于这是一个编译指示,它仅适用于 Windows(使用 Visual Studio 2008).为了让它在 Linux 上运行,我们尝试将以下内容添加到 A/initA.cpp:

Since this is a pragma, it only works on Windows (using Visual Studio 2008). To get it working on Linux, we've tried adding the following to A/initA.cpp:

extern void Af(void);
static void (*Af_fp)(void) = &Af;

这不会导致符号Af 包含在B 的最终链接中.我们如何强制将符号 Af 链接到 B 中?

This does not cause the symbol Af to be included in the final link of B. How can we force the symbol Af to be linked into B?

推荐答案

原来我最初的尝试大部分都在那里.以下作品:

It turns out my original attempt was mostly there. The following works:

extern "C" void Af(void);
void (*Af_fp)(void) = &Af;

对于那些想要一个独立的预处理器宏来封装它的人:

For those that want a self-contained preprocessor macro to encapsulate this:

#if defined(_WIN32)
# if defined(_WIN64)
#  define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:" #x))
# else
#  define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:_" #x))
# endif
#else
# define FORCE_UNDEFINED_SYMBOL(x) extern "C" void x(void); void (*__ ## x ## _fp)(void)=&x;
#endif

这样用的:

FORCE_UNDEFINED_SYMBOL(Af)

这篇关于链接到可执行文件时如何强制将目标文件包含在静态库中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆