我在生成构建设置方面遇到了麻烦,该构建设置允许分别使用gcc和MinGW在Linux和Windows中构建共享库.在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 $<
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 $<
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 $<
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中,它只包含bar的符号.这种分离对于库依赖于某些标准数值库(如BLAS)的情况非常重要.我希望能够部署共享库并使其依赖于用户计算机上的数值库的优化版本,而不是我自己的.
在任何情况下,创建共享库的正确过程是什么,在编译时并不是所有符号都存在?
如果重要的话,我在Linux上使用gcc 4.6.3编译这些示例,在Windows上使用gcc 4.7.2编译mingw-get-inst-20120426.exe.