来自C中存档(.a)文件的共享库

Abh*_*ngh 3 c linux makefile shared-libraries

我被赋予了从对象文件创建存档文件.a的任务,并从存档.a文件创建共享库文件.我尝试过以下文件:
foo.h

#ifndef _foo_h__
#define _foo_h__
extern void foo(void);
extern void bar(void); 
#endif //_foo_h__
Run Code Online (Sandbox Code Playgroud)


foo.c的

#include<stdio.h>

void foo(void)
{
    puts("Hello, I'm a shared library");
}
Run Code Online (Sandbox Code Playgroud)


bar.c

#include<stdio.h>

void bar(void)
{
    puts("This is bar function call.");
}
Run Code Online (Sandbox Code Playgroud)


main.c中

#include <stdio.h>
#include"foo.h"

int main(void)
{
    puts("This is a shared library test...");
    foo();
    bar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Makefile文件

CFLAGS = -Wall -Werror
LDFLAGS = -L/home/betatest/Public/implicit-rule-archive -Wl,-rpath,'$$ORIGIN'

all : run

run : main.o libfoo.so
    $(CC) $(LDFLAGS) -o $@ $^

libfoo.so : CFLAGS += -fPIC # Build objects for .so with -fPIC.
libfoo.so : libfoo.a
    $(CC) -shared -o $@ $^

libfoo.a : foo.o bar.o
    ar cvq libfoo.a foo.o bar.o
#   ar cr libfoo.a foo.o bar.o

# Compile any .o from .c. Also make dependencies automatically.
%.o : %.c
    $(CC) -c $(CFLAGS) -o $@ $<

#Include dependencies on subsequent builds.

.PHONY : all clean

clean :
    -rm -f *.o *.d run libfoo.*
Run Code Online (Sandbox Code Playgroud)

这个简单的测试程序似乎运行正常但在编译时使用它会产生错误:

cc -c -Wall -Werror -o main.o main.c
cc -c -Wall -Werror -fPIC  -o foo.o foo.c
cc -c -Wall -Werror -fPIC  -o bar.o bar.c
ar cvq libfoo.a foo.o bar.o
a - foo.o
a - bar.o
cc -shared -o libfoo.so libfoo.a
cc -L/home/betatest/Public/implicit-rule-archive -Wl,-rpath,'$ORIGIN' -o run main.o libfoo.so
main.o: In function `main':
main.c:(.text+0xf): undefined reference to `foo'
main.c:(.text+0x14): undefined reference to `bar'
collect2: ld returned 1 exit status
Makefile-test:7: recipe for target 'run' failed
make: *** [run] Error 1
Run Code Online (Sandbox Code Playgroud)

有人请指出我哪里出错?非常感谢.

zti*_*tik 6

如果您希望从静态库构建共享库,则必须告诉链接器使用静态库(.a)中包含的所有函数/符号.否则,共享库(.so)中不会包含任何内容.

你必须--whole-archive/--no-whole-archive在链接中使用pair.

CFLAGS = -Wall -Werror
LDFLAGS = -L/home/betatest/Public/implicit-rule-archive -Wl,-rpath,'$$ORIGIN'

all : run

run : main.o libfoo.so
    $(CC) $(LDFLAGS) -o $@ $^

libfoo.so : CFLAGS += -fPIC # Build objects for .so with -fPIC.
libfoo.so : libfoo.a
    $(CC) -shared -o $@ -Wl,--whole-archive $^  -Wl,--no-whole-archive

libfoo.a : foo.o bar.o
     ar cvq libfoo.a foo.o bar.o

# Compile any .o from .c. Also make dependencies automatically.
%.o : %.c
    $(CC) -c $(CFLAGS) -o $@ $<

#Include dependencies on subsequent builds.

.PHONY : all clean

clean :
    -rm -f *.o *.d run libfoo.*
Run Code Online (Sandbox Code Playgroud)

您可以使用以下nm命令检查导出的函数:

$ nm -D libfoo.so | grep  ' T '
0000000000000702 T bar
0000000000000714 T _fini
00000000000006f0 T foo
0000000000000590 T _init
Run Code Online (Sandbox Code Playgroud)

当没有使用--whole-archive/--no-whole-archive对时,你得到:

$ nm -D libfoo.so | grep  ' T '
0000000000000714 T _fini
0000000000000590 T _init
Run Code Online (Sandbox Code Playgroud)