用Makefile创建库文件的正确方法是什么? [C]
我正在为我的第一个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
这工作,但我还有什么需要改变?由于
您需要每个库的一组目标文件。 -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
每个库。
这条线是完全错误的:
$(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
文件和共享库链接到一个可执行文件?
如果你解释你真的想做什么,在更高层次上,我们可以提供帮助。
生病编辑我的主要职位,我想我应该更清楚。 – 2013-05-11 23:15:53
在您的编辑中,只要更新了其中一个对象文件,即告知make重新编译所有库。每个图书馆需要一个目标。 – Druesukker 2013-05-11 23:24:06
是的,我接受了你的建议,我尝试了一些东西,但它不起作用。我会用我现在拥有的一切重新编辑它。谢谢 – 2013-05-11 23:28:33
你有lib/variables.so而不是lib/libvariables.so – Druesukker 2013-05-11 23:31:59