GNU进行奇怪的变量替换

时间:2012-02-19 14:13:43

标签: linux makefile

我有以下Makefile:

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

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

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

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

我有files.html file2obj发出C源代码。此代码被编译为.o文件。

然而,make过程与我的预期略有不同。这是输出:

thrustmaster@thrustmaster:~/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中的一些已知错误?

任何建议/指示/建议将不胜感激: - )

谢谢


更新

我在这里提出另一个案例,我面临着类似的问题。

生成文件:

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 $@     #<--Issue in this line 

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

输出:

thrustmaster@thrustmaster:~/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

2 个答案:

答案 0 :(得分:3)

GNU Make有一个内置的隐式规则,用于从X.c构建文件X:

%: %.c
#  commands to execute (built-in):
    $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

当您运行“make”时,似乎会调用此隐式规则。

虽然不是一个好的永久性解决方案,但您可以通过使用-r(或--no-builtin-rules)选项运行make来禁用此问题,以禁用隐式规则。

答案 1 :(得分:2)

在第一种情况下,您正尝试使用此规则构建obj/static/files.html.o

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

在Make运行此规则之前,它将首先检查是否可以/应该重建先决条件(files.html)。有一个隐式规则将从files.html构建files.html.c,因此如果files.html.c存在将会发生。 (你似乎与Make所期望的方向相反;我不知道如何构建HTML以了解这是否是个好主意。)如果这样做有效,Make会认为files.html是{{3 },并在不再需要时删除它。

解决这个问题的方法不止一种。最简单的可能是编写自己的构建files.html的规则,它会否决Make的规则并且什么都不做:

%.html: %.html.c;

在第二种情况下,您在SOIL_UNITS变量中犯了一个小错误:

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

注意上一学期。您有obj/soil/%.o的规则,但不适用于soil/%.o,因此Make会依赖其隐式规则。只需将该字词更改为obj/soil/stb_image_aug.o