2013-05-11 136 views
1

我正在爲我的第一個Makefile創建一個簡單的shell系統。我需要製作庫文件,但由於某些原因庫部分沒有解決。在錯誤消息中說庫文件不存在(顯然)。用Makefile創建庫文件的正確方法是什麼? [C]

我是否錯過了可以解決這個問題的明顯問題?另外,還有什麼其他方法可以讓這個Makefile更高效?

# Beginning of Makefile 

OBJS = obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o 
HEADER_FILES = include/shell.h include/parser.h include/history.h include/hash_table.h include/variables.h 
EXECUTABLE = sshell 
LIBS = lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.so 
LIBCFLAGS = $(CFLAGS) -D_REENTRANT -fPIC 
CFLAGS = -Wall 
CC = gcc 
# End of configuration options 

#What needs to be built to make all files and dependencies 
all: $(EXECUTABLE) 

#Create the main executable 
$(EXECUTABLE): $(OBJS) $(LIBS) 
    $(CC) -o $(EXECUTABLE) obj/sshell.o -Llib -lparser -lshell -lhistory -lhash_table -lvariables 

#Create the library files 
$(LIBS): $(OBJS) 
    $(CC) $(LIBCFLAGS) -shared -o $(LIBS) $(OBJS) 

#Recursively build object files 
obj/%.o: src/%.c 
    $(CC) $(CFLAGS) -I./include/ -c $< -o [email protected] 

#Define dependencies for objects based on header files 
#We are overly conservative here, parser.o should depend on parser.h only 
$(OBJS) : $(HEADER_FILES) 

clean: 
    -rm -f $(EXECUTABLE) obj/*.o lib/*.so lib/*.a 
    -rm -f .sshell_history.txt 

run: $(EXECUTABLE) 
    (export LD_LIBRARY_PATH=lib; ./$(EXECUTABLE)) 

# End of Makefile 

謝謝! -Lily銀行

編輯:

之前,我試圖改變它,這裏是我曾與問候庫文件。

$(LIBS): $(OBJS) 
    $(CC) -shared -o lib/libparser.a obj/parser.o 
    $(CC) -shared -o lib/libshell.a obj/shutil.o 
    $(CC) -shared -o lib/libhistory.a obj/history.o 
    $(CC) -shared -o lib/libhash_table.a obj/hash_table.o 
    $(CC) -shared -o lib/libvariables.a obj/variables.o 

這樣做的問題是,它編譯每個文件五次,根本沒有效率。所以我想要做的就是一氣呵成。

EDIT2:

#Create the library files 
lib/libparser.so: obj/parser.o 
    $(CC) $(LIBFLAGS) -shared lib/libparser.a -o [email protected] 

lib/libshell.so: obj/shutil.o 
    $(CC) $(LIBFLAGS) -shared lib/libshell.a -o [email protected] 

lib/libhistory.so: obj/history.o 
    $(CC) $(LIBFLAGS) -shared lib/libhistory.a -o [email protected] 

lib/libhash_table.so: obj/hash_table.o 
    $(CC) $(LIBFLAGS) -shared lib/libhash_table.a -o [email protected] 

lib/variables.so: obj/variables.o 
    $(CC) $(LIBFLAGS) -shared lib/libvariables.a -o [email protected] 

不幸的是,這裏是我得到的錯誤:

make: *** No rule to make target `lib/libvariables.so', needed by `sshell'. Stop. 

的思考?

EDIT3:

#Create the library files 
lib/libparser.so: obj/parser.o 
    $(CC) $(LIBFLAGS) -shared $^ -o lib/libparser.a 

lib/libshell.so: obj/shutil.o 
    $(CC) $(LIBFLAGS) -shared $^ -o lib/libshell.a 

lib/libhistory.so: obj/history.o 
    $(CC) $(LIBFLAGS) -shared $^ -o lib/libhistory.a 

lib/libhash_table.so: obj/hash_table.o 
    $(CC) $(LIBFLAGS) -shared $^ -o lib/libhash_table.a 

lib/libvariables.so: obj/variables.o 
    $(CC) $(LIBFLAGS) -shared $^ -o lib/libvariables.a 

這工作,但我還有什麼需要改變?由於

+0

在您的編輯中,只要更新了其中一個對象文件,即告知make重新編譯所有庫。每個圖書館需要一個目標。 – Druesukker 2013-05-11 23:24:06

+0

是的,我接受了你的建議,我嘗試了一些東西,但它不起作用。我會用我現在擁有的一切重新編輯它。謝謝 – 2013-05-11 23:28:33

+0

你有lib/variables.so而不是lib/libvariables.so – Druesukker 2013-05-11 23:31:59

回答

2

您需要每個庫的一組目標文件。 -o標誌只有一個參數是輸出文件,你試圖輸出所有的庫文件,你不能用一次調用gcc來輸出。

你需要做的是這樣的:

lib/libshell.so: obj/sshell.o 
    $(CC) $(LIBFLAGS) -shared obj/sshell.o -o lib/libshell.so 

lib/libparser.so: obj/parser.o 
    $(CC) $(LIBFLAGS) -shared obj/parser.o -o lib/libparser.so 

每個庫。

2

這條線是完全錯誤的:

$(LIBS): $(OBJS) 
     $(CC) $(LIBCFLAGS) -shared -o $(LIBS) $(OBJS) 

如果展開所有的變量,此行應該是這樣的(添加換行符爲清楚起見):

lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.so: \ 
      obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o 
     gcc -Wall -D_REENTRANT -fPIC -shared -o lib/libshell.so lib/libparser.so lib/libhistory.so \ 
      lib/libhash_table.so lib/libvariables.so obj/shutil.o obj/parser.o obj/sshell.o obj/history.o \ 
      obj/hash_table.o obj/variables.o 

其中,它應該清楚,是非常不正確的。這是不對的,我甚至不知道你想要完成什麼。您是否真的想爲每個.o文件創建一個共享庫,其中每個共享庫都包含一個.o?如果是這樣,你爲什麼試圖將.o文件和共享庫鏈接到一個可執行文件?

如果你解釋你真的想做什麼,在更高層次上,我們可以提供幫助。

+0

生病編輯我的主要職位,我想我應該更清楚。 – 2013-05-11 23:15:53

相關問題