I am having problems generating the assembly, which allows me to create shared libraries on Linux and Windows using gcc and MinGW, respectively. On Linux, a shared library does not have to allow all dependencies at compile time; then how it looks on windows. Here is the problem setting:
$ cat foo.h #ifndef FOO_H #define FOO_H void printme(); #endif
$ cat foo.c #include "foo.h" #include <stdio.h> void printme() { printf("Hello World!\n"); }
$ cat bar.h #ifndef BAR_H #define BAR_H void printme2(); #endif
$ cat bar.c #include "bar.h" #include "foo.h" void printme2() { printme(); printme(); }
$ cat main.c #include "bar.h" int main(){ printme2(); }
$ cat Makefile .co: gcc -fPIC -c $< all: foo.o bar.o main.o gcc -shared foo.o -o libfoo.so gcc -shared bar.o -o libbar.so gcc main.o -Wl,-rpath=. -L . -lbar -lfoo -o main
Now on Linux this compiles and runs fine:
$ make gcc -fPIC -c foo.c gcc -fPIC -c bar.c gcc -fPIC -c main.c gcc -shared foo.o -o libfoo.so gcc -shared bar.o -o libbar.so gcc main.o -Wl,-rpath=. -L . -lbar -lfoo -o main $ ./main Hello World! Hello World!
On Windows, we need to change this to a dll, which is insignificant and accurate:
$ cat Makefile .co: gcc -fPIC -c $< all: foo.o bar.o main.o gcc -shared foo.o -o libfoo.dll gcc -shared bar.o -o libbar.dll gcc main.o -Wl,-rpath=. -L . -lbar -lfoo -o main
However, when we try to build, we get the following error:
$ make gcc -fPIC -c foo.c foo.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -fPIC -c bar.c bar.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -fPIC -c main.c main.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -shared foo.o -o libfoo.dll gcc -shared bar.o -o libbar.dll bar.o:bar.c:(.text+0x7): undefined reference to `printme' bar.o:bar.c:(.text+0xc): undefined reference to `printme' collect2.exe: error: ld returned 1 exit status make: *** [all] Error 1
Now we can fix the error by simply including the objects from foo.o in libbar.dll:
$ cat Makefile .co: gcc -fPIC -c $< all: foo.o bar.o main.o gcc -shared foo.o -o libfoo.dll gcc -shared bar.o foo.o -o libbar.dll gcc main.o -Wl,-rpath=. -L . -lbar -lfoo -o main $ make gcc -fPIC -c foo.c foo.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -fPIC -c bar.c bar.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -fPIC -c main.c main.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default] gcc -shared foo.o -o libfoo.dll gcc -shared bar.o foo.o -o libbar.dll gcc main.o -Wl,-rpath=. -L . -lbar -lfoo -o main $ ./main Hello World! Hello World!
However, I do not like this approach, since libbar.dll now contains characters for both foo and bar. On Linux, it contains only bar symbols. This separation is important in situations where the library depends on some standard number library, such as BLAS. I would like to be able to deploy the shared library and depend on the optimized version of the number library on the user's machine, and not on mine.
In any case, what is the correct procedure to create a shared library where not all characters are present at compile time?
In case it matters, I compiled these examples with gcc 4.6.3 on Linux and mingw-get-inst-20120426.exe with gcc 4.7.2 on Windows.