Reputation: 44444
I have the following 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
I have files.html
for which file2obj
emits C source code. This code gets compiled to .o file.
However the make
process is somewhat different that what I expected. Here's the output:
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
get invoked in this case? I expect gcc
. (I faced similar issues in another project too, but the results weren't serious.)-o
parameter is wrong.(I get -o files.html
)files.html
got deleted. Any ideas as to what can be the reason behind it? I am using GNU make 3.81.
Is there anything wrong with my Makefile code? Or is it some known bug in GNU/make?
Any advice/pointers/suggestiosn will be greatly appreciated :-)
Thanks
UPDATE
I am putting here another case, where I am facing a similar problem.
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 $@ #<--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
OUTPUT:
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
Upvotes: 1
Views: 338
Reputation: 99104
In the first case, you are trying to build obj/static/files.html.o
using this rule:
obj/static/%.o : %
@mkdir -p obj/static
file2obj $< $(subst .,_,$<) > $<.c
$(CCOMPILER) $<.c -o $@ -c $(FLAGS)
Before Make runs this rule, it will first check to see if the prerequisite (files.html
) can/should be rebuilt. There is an implicit rule that will build files.html
from files.html.c
, so that's what will happen if files.html.c
exists. (You seem to be going in the opposite direction from what Make expects; I don't know enough about building HTML to know if that's a good idea.) And if that works, Make will consider files.html
an intermediate file, and will delete it when it is no longer needed.
There's more than one way to solve this problem. The simplest is probably to write your own rule for building files.html
, which overrules Make's rule and does nothing:
%.html: %.html.c;
In the second case you made a small mistake in your SOIL_UNITS
variable:
SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o soil/stb_image_aug.o
Notice the last term. You have a rule for obj/soil/%.o
, but not for soil/%.o
, so Make falls back on its implicit rule. Just change that term to obj/soil/stb_image_aug.o
.
Upvotes: 2
Reputation: 336
GNU Make has a built-in implicit rule for building a file, X, from X.c:
%: %.c
# commands to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
It appears this implicit rule is being invoked when you run "make".
While not a good permanent solution, you may be able to avoid this problem by running make with the -r
(or --no-builtin-rules
) option to disable the implicit rules.
Upvotes: 3