2010-12-16 2 views
1

Я обновляю некоторые Makefile, чтобы перейти от Make 3.81 до 3.82. В нескольких местах, оригинальный автор использовал что-то вроде этого, чтобы построить статическую LIBS:

all: lib$(library).a($objects) 

Это, кажется, строить каждый файл .o в своей очереди, и вставьте его в .a используя ар:

g++ -O2 <snip> -o some_obj.o some_cpp.cpp 
ar rv libsome_lib.a some_obj.o 
etc... 

Эта новая версия сделает, хотя, дроссели с:

*** No rule to make target 'libsome_lib.a()', needed by 'all' 

Am I безопасно заменить этот ярлык с тем, как я привык делать это:

lib$(library).a: $(objects) 
    ar -rs lib$(library).a $objects 

Спасибо.

EDIT

Похоже, мне нужно лучше Makefile образование. Вот большая выдержка из оригинального файла Makefile:

CXXFLAGS += -O2 -g -Wall -Wunused-parameter \ 
    `pkg-config --cflags gthread-2.0 glibmm-2.4 gtkmm-2.4` 

libs += `pkg-config --libs gthread-2.0 glibmm-2.4` -lc 

%.d: %.cpp 
    $(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \ 
         | sed '\''s/\($*\)\.o[ :]*/\1.o [email protected] : /g'\'' > [email protected]; \ 
         [ -s [email protected] ] || rm -f [email protected]' 
%.d: %.c 
    $(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \ 
         | sed '\''s/\($*\)\.o[ :]*/\1.o [email protected] : /g'\'' > [email protected]; \ 
         [ -s [email protected] ] || rm -f [email protected]' 

from_sources = $(patsubst %.c,$(2),$(filter %.c, $(1))) $(patsubst %.cpp,$(2),$(filter %.cpp, $(1))) 

sources = $(shell cat sources.inc) 
objects = $(call from_sources,$(sources),%.o) 
depends = $(call from_sources,$(sources),%.d) 

library = some_lib 

.PHONY: all clean fresh 

all: lib$(library).a($(objects)) 

clean: 
    <SNIP> 

if neq($(MAKECMDGOALS),clean) 
    include $(depends) 
endif 

Когда это работает под 3.81, я получаю все .d зависимости создали, а затем сделать начинается г ++ ТРАЕКТОРИЙ OBJ файлов. В 3.82, я получаю файлы .d, но нет .o и делает сбой с «*** Нет правила делать ...»

+0

Для полноты, вы имеете в виду GNU Make? – beldaz 2010-12-16 03:38:25

+0

@beldaz, да извините GNU Make. – Mark 2010-12-16 03:41:38

+0

Предполагается, что это [функция вызова] (http://www.gnu.org/software/make/manual/make.html#Call-Function). Обратите внимание, что переменные типа = (в противоположность: = type) связывают последнее, заставляя это делать интересные вещи. Слишком умный для моего уставшего маленького мозга. – dmckee 2010-12-16 04:58:22

ответ

4

Это синтаксис «член архива», поддерживаемый в gnu make. Это немного интимно с инструментами для моих вкусов, но вот оно. Исходная ошибка может быть вызвана пустым значением $ (objects). Но я действительно не уверен. Вот некоторые документы:

http://www.gnu.org/software/make/manual/make.html#Archive-Members

11.1 архива в качестве целей

Индивидуальный член архивного файла может быть использован в качестве мишени или предпосылку в гриме. Вы указываете элемент члена имени в файловом архиве архива следующим образом:

archive(member) 

Эта конструкция доступна только в мишенях и предпосылок, а не в рецептах! Большинство программ, которые вы можете использовать в рецептах , не поддерживают этот синтаксис и не могут действовать непосредственно в архиве пользователей. Только ар и другие программы, специально предназначенные для работы на архивах, могут это сделать. Поэтому действительные рецепты для обновления архива цели-участника, вероятно, должны использовать ar. Например, это правило говорит создать hack.o члена в архиве foolib пути копирования файла hack.o:

foolib(hack.o) : hack.o 
     ar cr foolib hack.o 

В самом деле, почти все архивные цели членов обновленные именно так и есть неявное правило до сделайте это за вас. Обратите внимание: флаг 'c' для ar необходим, если файл архива еще не существует.

1

Возможно, у вас нет явного правила для преобразования чего-то вроде xyz.cpp в xyz.o, что вам может понадобиться для ваших источников, прежде чем пытаться вставлять их объекты в библиотеку. Там может быть подходящим неявным правилом для этого, поэтому сначала проверьте.

Первый вопрос, который я задал бы: что случилось с $objects, который заставил вас попытаться установить цель libsome_lib.a() (т. Е. Ничего между круглыми скобками)?

Чтобы быть честным, я стараюсь избегать этих правил, насколько это возможно, предпочитая явные утверждения зависимостей (если, конечно, не существует лота зависимостей). Да, я знаю, что это делает make-файлы более крупными и знаменует меня как по крайней мере частично луддитом, но я предпочитаю иметь вещи, которые просто работают над вещами, которые работают умно.

Cut'n'paste является одним из самых сильных инструментов в моем инструментарии :-)

3

Ваш путь выглядит хорошо, но там должно быть больше старого Makefile, если старый способ работал на всех.

О, и только для хорошей форме, я хотел бы предложить следующее:

lib$(library).a: $(objects) 
    ar -rs [email protected] $^ 

EDIT
Не чувствуйте себя плохо, не понимая, сделать очень хорошо; он имеет довольно кривую обучения.

Существует еще недостаточно, чтобы продолжить здесь, но если sources.inc не слишком большой, вы можете попробовать следующее в 3.81 и 3.82 и искать различие:

experiment: 
    @echo sources: $(sources) 
    @echo objects: $(objects) 
    @echo depends: $(depends) 

Доказательств до сих пор является то, что objects пусто под 3,82, но если .d файлов перестраиваются под 3,82, что свидетельствует о том, что depends является не пуст, что очень странно.

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