2015-02-11 108 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