2015-02-11 151 views
0

我在做makefile测试以创建静态库并从中创建动态库。我的目录中有foo.h foo.c bar.c和main.c文件。 我写了一个Makefile如下:Makefile共享库错误

#这个makefile演示了共享和静态库的创建。

CFLAGS = -Wall -Werror -fPIC 
CFLAGS1 = -Wall 
inc = /home/betatest/Public/implicit-rule-archive 

all : foo.o bar.o libfoo.a libfoo.so run 

foo.o: foo.c foo.h 
     @echo "Making the foo.o" 
     $(CC) -c $(CFLAGS) $< -o [email protected] 

bar.o : bar.c foo.h 
     @echo "Making the bar.o" 
     $(CC) -c $(CFLAGS) $< -o [email protected] 

libfoo.a(foo.o bar.o) : foo.o bar.o 
     ar cr [email protected] $^ 

libfoo.so : libfoo.a 
     $(CC) -shared -o [email protected] $^ 

run : main.c 
     $(CC) -L$(inc) $(CFLAGS1) -o [email protected] $< -lfoo 

.PHONY : clean 

clean : 
     -rm -f *.o run libfoo.* 

同时使得它提供了以下以下错误:

Making the foo.o 
cc -c -Wall -Werror -fPIC foo.c -o foo.o 
Making the bar.o 
cc -c -Wall -Werror -fPIC bar.c -o bar.o 
make: *** No rule to make target 'libfoo.a', needed by 'all'. Stop. 

我写的归档语句:

libfoo.a(foo.o bar.o) : foo.o bar.o 
     ar cr [email protected] $^ 

从这个到:

libfoo.a(*.o) : *.o 
     ar cr [email protected] $^ 

我可以写陈述吗?这是因为在这两种情况下,错误都是一样的。 我不明白我出错的地方。谢谢!!!!!

回答

1

而不是libfoo.a(foo.o bar.o)你想要普通libfoo.a : foo.o bar.o


另一件事是,.a文件正常构建针对最终的可执行联,用于.a被编译为依赖于位置的代码,因此目标文件。另一方面,共享库需要编译为位置独立的代码。

因此,您可以:

  1. 摆脱libfoo.a
  2. 自动生成标头依赖关系。
  3. 建立完整的目标依赖关系,以便make -j稳健运行。
  4. 设置rpath,以便run始终在其目录中找到libfoo.so

这样:

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

all : run 

run : main.o libfoo.so 
    $(CC) $(LDFLAGS) -o [email protected] $^ 

libfoo.so : CFLAGS += -fPIC# Build objects for .so with -fPIC. 
libfoo.so : foo.o bar.o 
    $(CC) -shared -o [email protected] $^ 

# Compile any .o from .c. Also make dependencies automatically. 
%.o : %.c 
    $(CC) -c $(CFLAGS) -o [email protected] -MD -MP $< 

# Include dependencies on subsequent builds. 
-include $(wildcard *.d) 

.PHONY : all clean 

clean : 
    -rm -f *.o *.d run libfoo.* 
+0

我所做的更改,但现在的问题是:'CC -c -Wall -Werror -fPIC的foo.c -o foo.o的 CC -c -Wall - Werror -fPIC bar.c -o bar.o ar cr libfoo.a foo.o bar.o cc -shared -o libfoo.so libfoo.a cc -L/home/betatest/Public/implicit-rule-归档-Wall -o运行main.c -lfoo /tmp/ccGKSd1I.o:在函数'main'中: main.c :(.text + 0xf):未定义对'foo'的引用 main.c :(。文本+ 0x14):未定义的引用“酒吧” collect2:ld返回1退出状态 Makefile:27:目标'运行'的配方失败 make:*** [run]错误1'如果手动使.so文件从.o文件中正常工作。但在这里它会给出错误。 – 2015-02-11 09:51:22

+0

你的.so中没有符号'foo'和'bar'。 – 2015-02-11 10:07:23

+0

谢谢@ MaximEgorushkin先生!!!!!!!!这工作。我想知道,在任何任务中,我们使用空格分隔列表编写多个标志,但在LDFLAGS中使用了逗号。所以它可以接受,或者有一些特殊情况。 ORIGIN还有一件事是检查变量类型的原始函数。请回复...非常感谢 – 2015-02-11 11:11:33