我有以下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
答案 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
。