Tôi đang gặp sự cố khi tạo thiết lập xây dựng cho phép các thư viện được chia sẻ trong cả Linux và Windows sử dụng gcc và MinGW tương ứng. Trong Linux, một thư viện chia sẻ không phải giải quyết tất cả các phụ thuộc tại thời gian biên dịch; trong khi đó, điều này có vẻ như trong Windows. Đây là thiết lập vấn đề:Tạo thư viện dùng gcc trên Linux và MinGW trên Windows
$ 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
Bây giờ, trong Linux, đây biên dịch và chạy tốt:
$ 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!
Trong Windows, chúng ta cần phải thay đổi như vậy để dll, đó là nhỏ và mịn:
$ 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
Tuy nhiên, khi chúng tôi cố gắng xây dựng, chúng tôi nhận được lỗi sau:
$ 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
Bây giờ, chúng ta có thể sửa lỗi bằng cách đơn giản bao gồm các đối tượng từ foo.o và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!
Tuy nhiên, tôi không thích cách tiếp cận này kể từ libbar.dll bây giờ chứa ký tự cho cả foo và bar. Trong Linux, nó chỉ chứa các biểu tượng cho thanh. Sự tách biệt này rất quan trọng đối với các tình huống mà thư viện phụ thuộc vào một số thư viện số chuẩn như BLAS. Tôi muốn có thể triển khai thư viện được chia sẻ và có nó phụ thuộc vào phiên bản được tối ưu hóa của thư viện số trên máy của người dùng chứ không phải của riêng tôi.
Trong mọi trường hợp, thủ tục thích hợp để tạo thư viện được chia sẻ là nơi không có tất cả các ký hiệu có mặt tại thời gian biên dịch là gì?
Trong trường hợp quan trọng, tôi đã biên soạn các ví dụ này với gcc 4.6.3 trên Linux và mingw-get-inst-20120426.exe với gcc 4.7.2 trên Windows.
Bạn đang thiếu '__declspec (dllimport) bắt buộc' và '__declspec (dllexport)' trong cả 'foo.h' và' bar.h'. Một cái gì đó như: '# nếu định nghĩa __ELF__ #define __attribute API ((tầm nhìn ("mặc định"))) #elif định nghĩa KHẨU #define API __declspec (dllexport) #else #define API __declspec (dllimport) #endif ' Sau đó' #define EXPORT' trong 'foo.c' và' bar.c'. – bit2shift
Giống như [this] (https://github.com/bit2shift/r3dVoxel/blob/master/inc/r3dVoxel/r3vABI.hpp#L7-L13) nhưng không có 'extern" C "', là một cấu trúc C++. – bit2shift