2012-02-19 22 views
1

我有以下生成文件:GNU發出奇怪的可變取代

CPPCOMPILER=g++ 
CCOMPILER=gcc 
#CPPCOMPILER=i586-mingw32msvc-g++ 

FLAGS=-Wall -g -O3 
LIBRARIES=-lpthread 
MODULES=obj/HTTPRequest.o obj/main.o obj/Server.o obj/SocketUtils.o obj/HTTPServer.o \ 
    obj/CookieManager.o obj/FileLister.o 
STATIC=obj/static/files.html.o obj/static/login.html.o 

all: $(MODULES) $(STATIC) 
    $(CPPCOMPILER) $(MODULES) $(STATIC) $(LIBRARIES) -o httpserver 

obj/main.o : main.cpp 
    @mkdir -p obj 
    $(CPPCOMPILER) -c $(FLAGS) $< -o [email protected] 

obj/static/%.o : % 
    @mkdir -p obj/static 
    file2obj $< $(subst .,_,$<) > $<.c 
    $(CCOMPILER) $<.c -o [email protected] -c $(FLAGS) #<-------***THIS LINE*** 

obj/%.o : %.cpp %.h 
    @mkdir -p obj 
    $(CPPCOMPILER) -c $(FLAGS) $< -o [email protected] 

clean: 
    rm -rf $(STATIC) $(MODULES) httpserver 

我有files.html爲其file2obj射出C源代碼。此代碼被編譯爲.o文件。

然而,make過程有點不同於我的預期。下面是輸出:

[email protected]:~/Code/HTTPFileSharer$ make 
cc  files.html.c -o files.html #<--------- ****THIS LINE!**** 
[and more linker errors here because of wrong command] 
make: *** [files.html] Error 1 
  • 如何cc被調用在這種情況下?我期待gcc。 (我也在另一個項目中遇到過類似的問題,但結果並不嚴重。)
  • 而且它怎麼會吃掉一些參數呢?還有-o參數有誤。(我得到-o files.html
  • 幾次files.html被刪除。任何想法可以成爲背後的原因?

我使用的是GNU make 3.81。

我的Makefile代碼有什麼問題嗎?或者它是GNU/make中的一些已知錯誤?

任何意見/指針/ suggestiosn將不勝感激:-)

感謝


UPDATE

我把這裏還有一種情況,在那裏我面臨着類似的問題。

的Makefile:

CPPCOMPILER=g++ 
CCOMPILER=gcc 
FLAGS=-Wall -pg -O3 
LIBRARIES=`pkg-config --libs libglfw` -lm -lGLU -lGL -lXrandr 
UNITS=obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o obj/PictureTile.o  obj/Coverflow.o obj/Vector3D.o \ 
     obj/TilePopulator.o obj/FileLister.o 
SOIL_DEPENDS=soil/image_DXT.c soil/image_helper.c soil/SOIL.c soil/stbi_DDS_aug_c.h  soil/stb_image_aug.c \ 
       soil/image_DXT.h soil/image_helper.h soil/SOIL.h soil/stbi_DDS_aug.h  soil/stb_image_aug.h 
SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o  soil/stb_image_aug.o 

all: $(SOIL_UNITS) $(UNITS) 
     $(CPPCOMPILER) $(FLAGS) $(SOIL_UNITS) $(UNITS) $(LIBRARIES) -o coverflow 

obj/soil/%.o : soil/%.c 
     @mkdir -p obj/soil 
     $(CCOMPILER) -c $< -o [email protected]  #<--Issue in this line 

obj/main.o : main.cpp 
     @mkdir -p obj 
     $(CPPCOMPILER) -c $(FLAGS) $< -o [email protected] 
obj/%.o : %.cpp %.h 
     @mkdir -p obj 
     $(CPPCOMPILER) -c $(FLAGS) $< -o [email protected] 
clean: 
     rm -rf $(UNITS) $(SOIL_UNITS) coverflow 

OUTPUT:

[email protected]:~/Code/Skroll$ make 
gcc -c soil/image_DXT.c -o obj/soil/image_DXT.o 
gcc -c soil/image_helper.c -o obj/soil/image_helper.o 
gcc -c soil/SOIL.c -o obj/soil/SOIL.o 
cc -c -o soil/stb_image_aug.o soil/stb_image_aug.c #<-----**THIS LINE** 
g++ -c -Wall -pg -O3 main.cpp -o obj/main.o 
g++ -c -Wall -pg -O3 TextureManager.cpp -o obj/TextureManager.o 
g++ -c -Wall -pg -O3 Thread.cpp -o obj/Thread.o 
g++ -c -Wall -pg -O3 Tile.cpp -o obj/Tile.o 
g++ -c -Wall -pg -O3 PictureTile.cpp -o obj/PictureTile.o 
g++ -c -Wall -pg -O3 Coverflow.cpp -o obj/Coverflow.o 
g++ -c -Wall -pg -O3 Vector3D.cpp -o obj/Vector3D.o 
g++ -c -Wall -pg -O3 TilePopulator.cpp -o obj/TilePopulator.o 
g++ -c -Wall -pg -O3 FileLister.cpp -o obj/FileLister.o 
g++ -Wall -pg -O3 obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o  soil/stb_image_aug.o obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o  obj/PictureTile.o obj/Coverflow.o obj/Vector3D.o obj/TilePopulator.o obj/FileLister.o `pkg- config --libs libglfw` -lm -lGLU -lGL -lXrandr -o coverflow 
+0

如果'files.html.c'比'files.html'更新,爲什麼不*要*重建'files.html'? – Beta 2012-02-19 15:08:45

+0

@貝塔我沒有得到你想要建議的。使用'file2obj'應用程序生成'files.html.c'(後來編譯成目標文件)。 – SuperSaiyan 2012-02-19 16:08:43

回答

2

在第一種情況下,您嘗試使用此規則,以建立obj/static/files.html.o

obj/static/%.o : % 
    @mkdir -p obj/static 
    file2obj $< $(subst .,_,$<) > $<.c 
    $(CCOMPILER) $<.c -o [email protected] -c $(FLAGS) 

make之前運行此規則,它會先檢查,看看如果前提條件(files.html)可以/應該被重建。有一個隱含的規則,將從files.html.c建立files.html,所以這會發生什麼如果files.html.c存在。 (你看起來與Make期望的方向相反;我不知道如何構建HTML來知道這是個好主意。)如果可行,Make會考慮0​​和intermediate file,並在不再需要時刪除它。

解決此問題的方法不止一種。最簡單的是可能要寫入構建files.html自己的規則,它否決製作的規則,什麼也不做:

SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o soil/stb_image_aug.o 

注意:

%.html: %.html.c; 

在第二種情況下,你在你的SOIL_UNITS可變犯了個小錯誤最後一屆。你有一個obj/soil/%.o的規則,但不是soil/%.o,所以Make回到它的隱含規則。只需將該術語更改爲obj/soil/stb_image_aug.o即可。

+0

這一個幫助:) 而它有點尷尬地看到,愚蠢的錯誤。!在第二種情況下(當時並沒有什麼差別 - gcc或cc都很好):P 在第一種情況下,我試圖做的是將'嵌入'文件到應用程序中程序。我爲同一個文件('file2obj')編寫了另一個實用程序,構建路徑是:'files.html' - >'files.html.c' - >'files.html.o' - >鏈接的可執行文件。我使用了規則:'obj/static /%。html.o:%.html',但我必須爲每個擴展添加一條新規則。任何其他出路(其中一個不失一般性?) 謝謝噸+1 :-) – SuperSaiyan 2012-02-20 05:54:16

+0

@Thrustmaster:呃?你想爲幾個不同的擴展使用*相同的規則* – Beta 2012-02-20 16:04:53

+0

是的!通過使用* .html,我必須編寫與擴展一樣多的規則。有什麼辦法可以編寫規則來處理特定目錄中的所有可能的文件(如在這個例如「靜態」文件夾中)?謝謝 :) – SuperSaiyan 2012-02-20 16:47:22

3

GNU製作已建立一個文件,X,從XC內置隱含規則:

%: %.c 
# commands to execute (built-in): 
    $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o [email protected] 

看樣子這個隱式規則在運行「make」時被調用。

雖然不是一個好的永久性解決方案,但您可以通過運行使用-r(或--no-builtin-rules)選項禁用隱式規則來避免此問題。

+0

我已經用另一個類似的案例更新了這個問題。如果你說的是正確的,它不應該影響所有的C文件嗎?它只是影響最後一個。任何想法爲什麼它發生? – SuperSaiyan 2012-02-19 16:15:49

+0

問題是這樣的規則:'OBJ /靜態/%○:%' 也許應該改爲:'OBJ /靜態/%○:%.c' 然後file2obj配方被劃分爲獨立的規則: '%.html.c:%的.html file2obj $ <$(SUBST,_,$ <) > $ Tim 2012-02-19 19:41:06