我从源代码构建 Inkscape:
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
$ ninja install
它返回错误如下。
[1002/1006] Building CXX object src/CMakeFiles/inkscape_base.dir/verbs.cpp.obj
[1003/1006] Linking CXX shared library bin\libinkscape_base.dll
FAILED: bin/libinkscape_base.dll src/libinkscape_base.dll.a
cmd.exe /C "cd . && C:\msys64\mingw64\bin\g++.exe -fopenmp -m64 -mms-bitfields -mthreads -mwindows -pthread -std=c++11 -g -shared -o bin\libinkscape_base.dll -Wl,--out-implib,src\libinkscape_base.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/inkscape_base.rsp && cd ."
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Error: export ordinal too large: 104116
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
什么原因会导致此错误以及如何解决?
注意:我可以成功构建 Inkscape,无需
-DCMAKE_BUILD_TYPE=Debug
。
用于编译 DLL 的符号太多,但我已成功使用以下命令以构建样式“调试”和静态链接来编译 Inkscape:
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -G Ninja ..
ninja install
在Windows平台上构建DLL时,有两种方法从DLL中导出函数。一种是按名称,即使用
__declspec(dllexport)
,另一种是按 序数 数字。导出函数的序号是通过将其附加到 .def
文件中的函数名称来定义的,如此处所述。LIBRARY MYLIB
EXPORTS
ActionA @1
ActionB @2
ActionC @3
ActionD @4
最大序数由 Microsoft PE 和 COFF 格式 定义。它是一个 16 位整数,最大为 65535。
只要 DLL 是使用
.def
文件构建的,就不太可能遇到问题,因为它通常少于在 .def
文件中显式导出的函数的最大数量。当导出的函数被显式修饰时也是如此。 MSVC 链接器不会从 DLL 导出其他函数。然而,GNU 链接器在缺少 .def
文件的情况下,会导出所有全局符号并达到限制并显示此错误消息。使用 ELF 格式的操作系统(例如 Linux)则不存在此问题,因为根据构建类型的限制是 32 位或 64 位,因此它不会影响共享库.so
。 .def
文件并在链接步骤中传递它。虽然,在 GCC 和 CLANG 中可以使用 -fvisibility=hidden
将默认可见性指定为隐藏,但截至 2022 年,Windows 不支持它。