I run Linux (specifically Ubuntu 20.04), and would like to know if there is a way to produce a dynamic library that could be linked against on a Windows machine. I am using GNU
make and a
mingw cross-compiler to attempt to do this.
Here is the simple makefile I have made for testing purposes:
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 $<
For reference: I have a file
example.hpp which declares the methods that I want to be included in the library, and these methods are defined in
test_exe.cpp contains my
main function, and calls methods defined in the library. Running
make generates (I believe) object files
test_exe.o, followed by a dynamically linked library named
example.dll and its corresponding import library named
libexample.a, and then links everything together into an executable called
main.exe. The produced output appears to be doing this, but I have no way of completely verifying if the output files are actually what I expect them to be.
Additionally, I have
CXX_FLAGS set to statically link the
c++ standard libraries because when I do not, I get an error saying
The application was unable to start correctly (0xc000007b). I am guessing this is because by default the files expect a Linux version of the standard libraries (which would not be found on a Windows machine), and explicitly linking overrides this option? Google says this error may indicate that I have the wrong application version for my machine, so it makes sense.
The echoed commands from when I run
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
When I link in Linux, everything works mostly as expected. The executable runs on Windows as long as the
.dll is in the current directory, and produces an error when it is removed.
The first thing I did not expect is that the executable will run whether or not the import library
libmath.a is present. I was under the assumption that I was linking against the import library which indirectly wraps the dynamic library, but this does not appear to be the case. Does anyone know what is actually happening, and why I am not linking against the import library?
My other question takes a bit more explanation. Ideally, I would like to be able to create a dynamic library on Linux, send it to a Windows machine, and link it into an arbitrary executable there. I am not entirely sure if this is possible, because Windows has to specify
__declspec(dllexport) while Linux does not, but would like to know if it is. I have tried moving my dynamic and import libraries (
libexample.a), along with my library header file (
example.hpp) into a directory with a new file (
testapp.cpp) specifying an alternate
On a Windows machine, I run
g++ -c testapp.cpp to produce an object file, and then try to link. When I run
g++ -o app.exe testapp.o -L. -lexample to try to generate an executable linked to the dynamic library (through the import library) I get the following error:
undefined reference to 'square(int)'.
square(int) is a function that is defined in the library, returning the square of an integer. I have also tried marking the function in my header file as
__declspec(dllimport), which changes the error message to:
undefined reference to '_imp___Z6squarei'. Is it possible on Windows to link against a .dll that did not originally specify
__declspec(dllexport) for its functions (i.e. one developed in Linux)?
Build OS: Ubuntu 20.04 - version 9.3.0 of g++
Target OS: Windows 10 (tested in a virtualbox vm) - version 9.2.0 of g++
I eventually got it. The command that worked was:
g++ -o alt.exe testapp.o libexample.a. I am not entirely sure why this works when what I tried before did not, but it does work as expected now.
Interestingly, it still works even if I do not specify
__declspec(dllimport) anywhere. I am also not sure why this works, but my best guess is that I am still using a GNU compiler, and not a windows default one.
User contributions licensed under CC BY-SA 3.0