2015-02-11 3 views
0

Я делал тест makefile для создания статической библиотеки и создания из нее динамической библиотеки. У меня есть файлы foo.h foo.c bar.c и main.c в моем каталоге. Я написал Makefile следующим образом:Ошибка в общей библиотеке Makefile

# Этот make-файл демонстрирует создание общей и статической библиотеки.

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] $^ 

Могу ли я написать утверждение l ike это потому, что в обоих случаях ошибка одна и та же. Я не понимаю, где я ошибаюсь. Благодаря!!!!!

ответ

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

Я сделал изменения, но теперь проблема: '-c куб.см -Wall -Werror -fPIC foo.c -o foo.o куб.см -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): неопределенная ссылка на 'bar ' collect2: ld возвращено 1 статус выхода Makefile: 27: рецепт для цели 'run' failed make: *** [run] Ошибка 1' Если я вручную создаю файлы .so из файлов .o, он отлично работает. но здесь он дает ошибку. –

+0

У вас нет символов 'foo' и' bar', определенных в вашем .so. –

+0

Спасибо @ MaximEgorushkin сэр !!!!!!!! Это сработало. Я хочу знать, что в любом задании мы пишем несколько флагов с разделенным пробелом списком, но в LDFLAGS вы использовали запятую. Так ли это приемлемо или у него есть особый случай. И еще одна вещь ORIGIN - это функция происхождения для проверки типа переменной. Ответьте, пожалуйста...Большое спасибо –

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