2013-05-11 4 views
1

Я делаю свой первый Makefile для простой оболочки. Мне нужно создавать файлы библиотеки, но по какой-то причине раздел библиотеки не работает. В сообщении об ошибке говорится, что файлы библиотеки не существуют (очевидно).Каков правильный способ создания файлов библиотеки с помощью 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 Банки

Edit:

Прежде чем я попытался изменить его, вот что я имел в отношении файлов библиотек.

$(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

+0

Да, я принял ваш совет, и я что-то пробовал, но он не работает. Я отредактирую его снова с тем, что у меня есть сейчас. Спасибо –

+0

У вас есть lib/variables.so и не lib/libvariables.so – Druesukker

ответ

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

плохо редактировал мой основной пост с тем, что у меня было до того, как я предполагаю, что я должен быть более ясным. –

Смежные вопросы