Создание общей библиотеки с использованием gcc в Linux и MinGW в Windows

У меня возникли проблемы с созданием конфигурации сборки, которая позволяет создавать общие библиотеки в Linux и Windows, используя gcc и MinGW соответственно. В Linux общая библиотека ненеобходимо разрешить все зависимости во время компиляции; в то время как это происходит в случае с Windows. Вот проблема настройки:

$ cat foo.h 
#ifndef FOO_H
#define FOO_H
void printme();
#endif
$ cat foo.c
#include "foo.h"
#include 
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 
.c.o:
        gcc -fPIC -c 
$ cat Makefile 
.c.o:
        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
lt; 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

Теперь в Linux это компилируется и работает просто отлично:

$ 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!

В Windows нам нужно изменить это на dll, что является незначительным и хорошим:

$ cat Makefile 
.c.o:
        gcc -fPIC -c 
$ cat Makefile 
.c.o:
        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
lt; 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

Однако, когда мы пытаемся построить, мы получаем следующую ошибку:

$ 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

Теперь мы можем исправить ошибку, просто включив объекты из foo.o в libbar.dll:

$ cat Makefile 
.c.o:
        gcc -fPIC -c 
$ cat Makefile 
.c.o:
        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!
lt; 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!

Тем не менее, я неМне не нравится этот подход, поскольку libbar.dll теперь содержит символы для foo и bar. В Linux он содержит только символы для бара. Это разделение важно для ситуаций, когда библиотека зависит от некоторой стандартной числовой библиотеки, такой как BLAS. Я'я хотел бы иметь возможность развертывать разделяемую библиотеку и зависеть от оптимизированной версии числовой библиотеки от пользователя 'Машина не моя, а моя.

В любом случае, чтоправильная процедура для создания разделяемой библиотеки, где не все символы присутствуют во время компиляции?

В случае, если это имеет значение, я скомпилировал эти примеры с помощью gcc 4.6.3 для Linux и mingw-get-inst-20120426.exe с gcc 4.7.2 для Windows.

Ответы на вопрос(1)

Ваш ответ на вопрос