我可以在 Linux 上编译动态库,在 Windows 上编译 link 吗?

Can I compile a dynamic lib on Linux and link on Windows?

我运行 Linux(特别是Ubuntu 20.04),想知道是否有办法生成可以link编辑的动态库在 Windows 机器上。我正在使用 GNU makemingw 交叉编译器来尝试执行此操作。

这是我为测试目的制作的简单 makefile:

CXX := x86_64-w64-mingw32-g++
CXX_FLAGS := -static-libgcc -static-libstdc++

main.exe: example.dll test_exe.o
    $(CXX) $(CXX_FLAGS) -o main.exe test_exe.o -L. -lexample

example.dll: example.o
    $(CXX) $(CXX_FLAGS) -shared -o example.dll example.o -Wl,--out-implib,libexample.a

%.o: %.cpp
    $(CXX) -c -fPIC $<

供参考:我有一个文件example.hpp,它声明了我想包含在库中的方法,这些方法在example.cpp中定义。 test_exe.cpp 包含我的 main 函数,并调用库中定义的方法。 运行 make 生成(我相信)目标文件 example.otest_exe.o,然后是一个名为 example.dll 的动态 linked 库及其相应的导入名为 libexample.a 的库,然后 link 将所有内容一起放入名为 main.exe 的可执行文件中。生成的输出似乎是这样做的,但我无法完全验证输出文件是否真的符合我的预期。

此外,我将 CXX_FLAGS 静态设置为 link cc++ 标准库,因为当我不这样做时,我会收到一条错误消息 The application was unable to start correctly (0xc000007b).我猜这是因为默认情况下文件需要标准库的 Linux 版本(在 Windows 机器上找不到),并且明确地 linking 覆盖了这个选项? Google 说这个错误可能表明我的机器的应用程序版本错误,所以这是有道理的。

我 运行 make 时的回显命令是:

x86_64-w64-mingw32-g++ -c -fPIC example.cpp
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -shared -o example.dll example.o -Wl,--out-implib,libexample.a
x86_64-w64-mingw32-g++ -c -fPIC test_exe.cpp
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -o main.exe test_exe.o -L. -lexample

当我在 Linux 中 link 时,一切都按预期进行。只要 .dll 在当前目录中,Windows 上的可执行文件 运行s 就会在删除时产生错误。

我没想到的第一件事是,无论导入库 libmath.a 是否存在,可执行文件都会 运行。我假设我 link 反对间接包装动态库的导入库,但事实并非如此。有谁知道实际发生了什么,以及为什么我不 link 反对导入库?

我的另一个问题需要更多解释。理想情况下,我希望能够在 Linux 上创建一个动态库,将其发送到 Windows 机器,然后 link 将其发送到那里的任意可执行文件中。我不完全确定这是否可行,因为 Windows 必须指定 __declspec(dllexport) 而 Linux 不需要,但我想知道是否可以。我尝试将我的动态库和导入库(example.dlllibexample.a)连同我的库头文件 (example.hpp) 移动到一个包含新文件 (testapp.cpp) 的目录中指定备用 main 方法。

在一台Windows机器上,我运行g++ -c testapp.cpp生成一个目标文件,然后尝试link。当我 运行 g++ -o app.exe testapp.o -L. -lexample 尝试生成可执行文件 linked 到动态库(通过导入库)时,我收到以下错误:undefined reference to 'square(int)'square(int) 是库中定义的函数,返回整数的平方。我还尝试将头文件中的函数标记为 __declspec(dllimport),这会将错误消息更改为:undefined reference to '_imp___Z6squarei'。是否有可能在 Windows 到 link 上针对最初未为其功能指定 __declspec(dllexport) 的 .dll(即在 Linux 中开发的)?

构建 OS:Ubuntu 20.04 - g++ 版本 9.3.0

目标 OS:Windows 10(在 virtualbox 虚拟机中测试)- g++

版本 9.2.0

我终于明白了。有效的命令是:g++ -o alt.exe testapp.o libexample.a。我不完全确定为什么我之前尝试过的方法不起作用,但它现在确实可以正常工作。

有趣的是,即使我没有在任何地方指定 __declspec(dllimport) 它仍然有效。我也不确定为什么会这样,但我最好的猜测是我仍在使用 GNU 编译器,而不是 windows 默认编译器。