我可以在 Linux 上编译动态库,在 Windows 上编译 link 吗?
Can I compile a dynamic lib on Linux and link on Windows?
我运行 Linux(特别是Ubuntu 20.04),想知道是否有办法生成可以link编辑的动态库在 Windows 机器上。我正在使用 GNU make
和 mingw
交叉编译器来尝试执行此操作。
这是我为测试目的制作的简单 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.o
和 test_exe.o
,然后是一个名为 example.dll
的动态 linked 库及其相应的导入名为 libexample.a
的库,然后 link 将所有内容一起放入名为 main.exe
的可执行文件中。生成的输出似乎是这样做的,但我无法完全验证输出文件是否真的符合我的预期。
此外,我将 CXX_FLAGS
静态设置为 link c
和 c++
标准库,因为当我不这样做时,我会收到一条错误消息 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.dll
和 libexample.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 默认编译器。
我运行 Linux(特别是Ubuntu 20.04),想知道是否有办法生成可以link编辑的动态库在 Windows 机器上。我正在使用 GNU make
和 mingw
交叉编译器来尝试执行此操作。
这是我为测试目的制作的简单 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.o
和 test_exe.o
,然后是一个名为 example.dll
的动态 linked 库及其相应的导入名为 libexample.a
的库,然后 link 将所有内容一起放入名为 main.exe
的可执行文件中。生成的输出似乎是这样做的,但我无法完全验证输出文件是否真的符合我的预期。
此外,我将 CXX_FLAGS
静态设置为 link c
和 c++
标准库,因为当我不这样做时,我会收到一条错误消息 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.dll
和 libexample.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 默认编译器。