2010-12-16 50 views
1

我正在更新一些Makefiles從Make 3.81移動到3.82。在多個地方,原作者使用像這樣建立靜態庫:

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

這似乎構建每個.o文件將依次使用AR其插入到.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' 

我是否可以安全使用我已經習慣了這樣的方式替換該快捷方式

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

謝謝。

編輯

看起來我需要一個更好的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依賴性創建,然後作出啓動G ++荷蘭國際集團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

[call function](http://www.gnu.org/software/make/manual/make.html#Call-Function)應該做什麼。請注意= type(而不是:= type)變量綁定的方式,導致它做了有趣的事情。我的疲倦的小腦子太聰明瞭。 – dmckee 2010-12-16 04:58:22

回答

4

這是gnu make支持的「歸檔成員」語法。對於我的口味來說,這與工具有點太親密了,但它就是這樣。原始錯誤可能是由$(對象)爲空造成的。但我真的不確定。下面是一些文檔:

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

11.1歸檔成員爲靶

的存檔文件的個別成員可以作爲目標或在化妝 先決條件。您在存檔文件 歸檔指定成員命名的成員如下:

archive(member) 

此構造僅在目標和先決條件可用,而不是在食譜!您可能在 配方中使用的大多數程序都不支持此語法,因此無法直接在存檔 成員上執行操作。只有專門設計用於在檔案上操作 的ar和其他程序纔可以這樣做。因此,更新檔案 成員目標的有效配方可能必須使用ar。例如,該規則說要 通過複製文件hack.o創建歸檔foolib成員hack.o:

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

事實上,幾乎所有的檔案成員目標是在短短這種方式更新,有一個隱含規則到 爲你做。請注意:如果 存檔文件尚不存在,則需要'c'標記爲ar。

1

可能,但您沒有明確的規則來轉換類似xyz.cppxyz.o之類的內容在嘗試將其對象注入庫之前,您可能需要獲取源代碼。有可能是一個合適的隱含規則,這首先檢查。

我會問的第一個問題是:$objects發生了什麼事情,導致您嘗試並將第一個目標的libsome_lib.a()(即括號之間沒有任何內容)作爲目標?老實說,我傾向於儘可能地避免這些包含規則,更喜歡明確的依賴關係聲明(當然,除非有依賴關係存在很多)。是的,我知道這會讓makefile變得更大,並且將我標記爲至少是一個部分luddite,但我更喜歡擁有能夠巧妙工作的東西。

Cut'n'paste是在我的工具箱中的最強工具:-)

+0

請看上面,看起來像我需要我更多的學習。 – Mark 2010-12-16 03:42:32

+0

Luddite!勒德!當然,這裏使用的特定機制對我來說是全新的。我現在必須去閱讀文檔... – dmckee 2010-12-16 04:48:52

+0

除了一旦獲得gcc自動依賴關係生成權,您再也不必爲維護複雜的makefile而煩惱了。 – 2010-12-16 13:35:54

3

你的方式看起來不錯的,但如果老辦法曾在所有必須有更多的老Makefile文件。

哦,只是爲了好形式,我建議這樣的:

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

編輯
不要覺得不好不理解做非常好;它有相當的學習曲線。

這裏還不夠,但如果sources.inc不是太大,你可以在3.81和3中試試以下內容。82,尋找差異:

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

迄今爲止的證據是,objects 3.82之下是空的,但如果.d文件正在3.82下重建這表明depends空的,這是很奇怪的。

+0

謝謝,請參閱附加信息。 – Mark 2010-12-16 03:42:58