如何告诉 MinGW 链接器不要导出所有符号?

How to tell the MinGW linker not to export all symbols?(如何告诉 MinGW 链接器不要导出所有符号?)

本文介绍了如何告诉 MinGW 链接器不要导出所有符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 MinGW 工具链构建一个 Windows 动态库.

I'm building a Windows dynamic library using the MinGW toolchain.

为了构建这个库,我静态链接到提供 API 的其他 2 个库,并且我有一个 .def 文件,我在其中编写了我想在我的库中导出的唯一符号.

To build this library I'm statically linking to other 2 which offer an API and I have a .def file where I wrote the only symbol I want to be exported in my library.

问题是 GCC 正在导出所有符号,包括我链接到的库中的符号.有没有办法告诉链接器只导出 def 文件中的符号?

The problem is that GCC is exporting all of the symbols including the ones from the libraries I'm linking to. Is there anyway to tell the linker just to export the symbols in the def file?

我知道有选项 --export-all-symbols 但似乎没有相反的选项.

I know there is the option --export-all-symbols but there seems not to be the opposite to it.

现在构建脚本的最后一行具有这样的结构:

Right now the last line of the build script has this structure:

g++ -shared CXXFLAGS DEFINES INCLUDES -o library.dll library.cpp DEF_FILE 
OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

在关于链接器的 docs 中,它说 --export-all-symbols 是默认行为,如果您提供 def 文件,则当您不明确使用该选项时,它会被禁用,除非它没有;无论如何,第 3 方库中的符号正在被导出.

In the docs about the linker it says that --export-all-symbols is the default behavior and that it's disabled when you don't use that option explicitly if you provide a def file, except when it doesn't; the symbols in 3rd party libs are being exported anyway.

添加选项 --exclude-libs LIBS--exclude-symbols SYMBOLS 不会阻止库中的符号被导出.

Adding the option --exclude-libs LIBS or –exclude-symbols SYMBOLS doesn't prevent the symbols from the libraries from being exported.

推荐答案

如果您的 binutils 发行版(本机或交叉编译)提供 dllwrap,您可以使用它.

You can use dllwrap if your distribution of binutils (either native or cross compiling) provides it.

它可以使用 DEF 文件中的接口生成 DLL(在后台它调用 gcc、ld 和 dlltool 来执行此操作).使用这个和直接将 DEF 文件传递​​给 GCC 的区别在于文件中的定义被区别对待.

It can produce DLLs using the interface in a DEF file (under the hood it calls gcc, ld and dlltool to do so). The difference between using this and passing a DEF file to GCC directly is that the definitions in the file are treated differently.

例如,如果您在导出文件中有符号重命名:

For example, if you have a symbol rename in the export file:

_SomeFuntion = _SomeFunction@12

GCC 将创建 2 个导出,一个名为 _SomeFunction,另一个具有修饰名称,而 dllwrap 只会导出 _SomeFuntion.因此,如果您只将要导出的符号添加到 DEF 文件中,您最终只会在库中使用它们.

GCC will create 2 exports, one by the name of _SomeFunction and the other one with the decorated name while dllwrap will only export _SomeFuntion. So if you only add to the DEF file the symbols you want to be exported you will end up only with them in the library.

dllwrap 默认使用 C 编译器驱动程序,因为它无法知道其他情况.当您链接 C++ 代码时,您必须使用选项 --driver-name c++ 来设置驱动程序.如果您碰巧有带前缀的 MinGW 可执行文件,则必须将其也包含在驱动程序名称中(例如 i686-mingw32-c++ 而不是 c++),您可能需要也可以使用选项 --dlltool-name.

dllwrap by default uses the C compiler driver since it has no way of knowing otherwise. As you're linking C++ code, you have to use the option --driver-name c++ to set the driver. If you happen to have the MinGW executables with a prefix you have to include it too in the driver name (e.g. i686-mingw32-c++ instead of c++) and you may need to use the option --dlltool-name too.

尝试使用这两行而不是您发布的那一行:

Try using these two lines instead of the one you posted:

g++ -c CXXFLAGS DEFINES INCLUDES -o library.o library.cpp
dllwrap -o library.dll --driver-name c++ --def DEF_FILE OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

第一个从library.cpp的代码生成一个目标文件,第二个组装动态库.OBJECT_FILES 东西(我假设它是您之前生成的其他目标文件)也应该有 library.o.

The first one generates an object file from the code of library.cpp and the second one assembles the dynamic library. The OBJECT_FILES thing (which I assume to be other object files you generated previously) should have library.o there too.

也就是说,我必须告诉你 dllwrap 已经是 2006 年弃用,官方 binutils 包中没有相关文档;要获取一些信息,您可以像往常一样使用 --help 调用它.如果您也需要它,它可以生成一个导入库.

That said, I have to tell you dllwrap was already deprecated in 2006 and there is no documentation on it in the official binutils package; to get some info you may call it with --help as usual. It can generate an import library in case you need it too.

这篇关于如何告诉 MinGW 链接器不要导出所有符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何告诉 MinGW 链接器不要导出所有符号?

基础教程推荐