gccとMinGWを使ってLinuxとWindowsの両方で共有ライブラリを構築できるビルド設定の生成に問題があります。 Linuxでは、共有ライブラリはコンパイル時にすべての依存関係を解決する必要はありません。これはWindowsの場合と同じです。ここでは、問題設定は次のとおりです。Linuxでgcc、WindowsでMinGWを使って共有ライブラリを構築する
$ 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
.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
今、私たちは単にlibbar.dllへの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!
、私はこのアプローチを好きではありませんフーとバーの両方のために。 Linuxでは、barのシンボルしか含まれていません。この分離は、ライブラリがBLASのような標準的な数値ライブラリに依存している場合に重要です。私は共有ライブラリを配備して、それをユーザのマシン上の数値ライブラリの最適化バージョンに依存させることができたいと思います。
いずれの場合でも、コンパイル時にすべてのシンボルが存在しない共有ライブラリを作成する適切な手順は何ですか?
重要な場合は、これらの例をLinuxの場合はgcc 4.6.3、Windowsの場合はgcc 4.7.2のmingw-get-inst-20120426.exeでコンパイルしました。
'foo.h'と' bar.h'の両方で、必要な '__declspec(dllimport)'と '__declspec(dllexport)'がありません。定義されたEXPORT #elifの 'の#if()は(可視性( "デフォルト"))__ELF__ の#define APIの__attributeを定義し の#define APIの__declspec(のdllexport) の#else の#define APIの__declspec(dllimportの) #endifの:ような何か' ' 'foo.c'と' bar.c'に '#define EXPORT'があります。 – bit2shift
[this](https://github.com/bit2shift/r3dVoxel/blob/master/inc/r3dVoxel/r3vABI.hpp#L7-L13)のようなものですが、C++の構造体である 'extern" C "はありません。 – bit2shift