makefile: Why does this simple makefile only process the first source file? - c++

[SOLVED]
I'm having trouble getting this simple makefile to work properly.
This should build the three source files NeonAs1.cpp NeonAs2.cpp NeonAs3.cpp to object files in the 'obj' folder.
This works but it only ever attempts to build NeonAs1.cpp and then completes without error.
Any ideas?
WORKSPACE=../../workspace/
SRC_FOLDER=$(WORKSPACE)/ProjectNeon/
LOCAL_SRC_FILES=NeonAs1.cpp NeonAs2.cpp NeonAs3.cpp
vpath %.cpp $(SRC_FOLDER)
OBJECTS = $(patsubst %.cpp,obj/%.o,$(LOCAL_SRC_FILES))
$(OBJECTS): | obj
obj:
#mkdir -p $#
obj/%.o : %.cpp
#echo $<
#$(CXX) $(CXXFLAGS) -c $< -o $#
clean:
-rm -f $(LIBRARY) obj/*.o
Update 1: if I add a explicit all target like:
all: $(OBJECTS)
Then if I do an explicit:
make all
It works fine.. How can I make it work when I just do a make with no 'all' target
Update 2: Solved, I just needed to move my all target above the $(OBJECTS) target.

The default behavior of make is to only build the first target listed in your Makefile. I don't see any target listed earlier than $(OBJECTS): | obj. Therefore, the "first target rule" will build the first thing listed in $(OBJECTS).
To get all of your $(OBJECTS) built, you need a target for your final executable that depends on $(OBJECTS).
To make your Makefile meet common convention, you'll want to list a target named all early in your Makefile that depends on your executable as well. That way, when you type make or make all, it will build your $(OBJECTS) and your executable.
For debugging purposes, you might add a target named debugvars: that just executes #echo OBJECTS=$(OBJECTS) to make sure $(OBJECTS) is set as you expect. To run that target, you can then type make debugvars. That's a handy trick I've used many times to debug variables in a Makefile.

Related

Is there a way to make a makefile for c++ that will run the program every time you use the make command?

I have a makefile for a C++ project that compiles and creates an executable for the program, and then runs that executable. The problem is, I want the executable to be run every time I use the make command, but if there have been no changes to the source that need to be recompiled, make will come back with “make: nothing to be done.” Is there a way to format the makefile so that it will compile and run if compilation is needed, otherwise just run the executable?
You can simply add a new target to run the program and make that target depend on the creation of the program. If you make that target a dependency of the default target (all:) it will always run the program after a successful build.
Like this:
SOURCES = ./src/main.cpp
OBJECTS = ./bin/main.o
# default target to build hello executable & run it if successful
all: hello run
hello: $(OBJECTS)
$(CXX) -o $# $^
bin/%.o : src/%.cpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $< $(LDFLAGS)
run: hello
./hello
clean:
#rm -rf hello $(OBJECTS)
.PHONY: all run clean
Note: There is nothing special about the target name "run". I could have called it "wibble".

Makefile in sub-directory

I am trying to write a makefile in a subdirectory of my eclipse makefile project.
MyProject \
test.cpp
Build\
Makefile
I am also trying to create a generic makefile. I am having trouble defining the targets since the build is not happening in the same directory as the source.
CC = g++
CC_FLAGS = -g3
EXEC = test
SOURCEDIR = ..
SOURCES = $(shell find $(SOURCEDIR) -name '*.c' -o -name '*.cpp')
OBJECTS = $(addsuffix .o,$(subst ../,,$(SOURCES)))
.DEFAULT_GOAL = all
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
.PHONY: clean
clean:
rm -f $(EXEC) $(OBJECTS)
.PHONY: all
all: $(EXEC)
Right now when I build I get the error...
make all
make: *** No rule to make target 'test.cpp.o', needed by 'test'. Stop.
Can anyone tell me why this is not working or recommend a better approach.
If you change your dependency from object to source as follows:
%.cpp.o: $(SOURCEDIR)/%.cpp
it seems to work.
In general I would prefer to NOT do anything in a build dir, because I personally expect a build dir is a temporary dir which can be removed completely for distribution which is not the case if the Makefile resists there. But this is a matter of taste.
Also I do not prefer to use all c/cpp you find as objects/sources in the make process. If you need to add files for different variants in your projects, you enter a nightmare to change all these things later.
And also as a hint: Typically objects are <basename>.o and not <basename>.cpp.o
And another one:
Users expect that the clean target also remove the executable. If not, you will never see a rebuild by simply do make clean; make, because the executable is in place and all dependencies are fulfilled.

Using makefile arguments without foo=

I have a makefile I use to compile a single file. When I need to pass an argument, I use target=targetFile.
The script takes the argument, looks for the file (within the same directory) that has the same value as the argument and compiles it.
I use this for compiling problems from uhunt and uva, which use a single c++ file. So I dont' need multiple makefiles for multiple source files. Single makefile for multiple source files is the reason I made the makefile.
Here's the code I have so far
OBJS = $(target).o
CC = g++
CFLAGS = -Wall -g -std=c++11
INCLUDE = -I./$(target)
#default command to run
all : Main-$(target) clean run
#compile and build
Main-$(target) : $(OBJS)
$(CC) $(CFLAGS) $^ -o $#
%.o : %.cpp
$(CC) -c $(CFLAGS) $<
#remove object and any other garbage files.
clean:
rm -rf -d $(target).o *~ *% *# .#*
#remove the compiled file
clean-all:
$(clean) rm Main-$(target)
#run the compiled file
run:
./Main-$(target)
The command I use to compile is,
make target=sourceFile
Also I don't include the file extension, I have all my source file extensions to be cpp
What I want in the end is:
make sourceFile
Just a side note, for using the command clean and clean-all, I use
make target=sourceFile clean
make target=sourceFile clean-all
I'd prefer if I can use:
make sourceFile clean
make sourceFile clean-all
You may use common Makefile variable MAKECMDGOALS that contains all targets passed to make.
Please try this variant
CC = g++
CFLAGS = -Wall -g
MAKECMDGOALS := $(filter-out clean, $(MAKECMDGOALS))
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
clean:
rm -f *.o
Here the lines
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
will generate separate build targets for each word in MAKECMDGOALS.
Note, we need this Makefile to know that 'clean' is a target for removing stuff, but not to attempt build Main-clean. This why we remove clean from MAKECMDGOALS using filter-out function.
So if we run make a b clean, the build system will generate automatically targets for building Main-a and Main-b and then use already written clean target
Disclaimer -- this is a non-standard use of Make, and will therefore open up all kinds of corner cases, so I don't recommend it. This is better suited for a shell script calling make. That being said... it is an interesting question.
You can't do make xxx clean, and not have it try to build xxx (unless you do some really nasty cludge using recursive make, but I won't go there). You could do something like make clean-xxx though, as follows:
%:Main-%
Main-%:%.cpp
$(CC) $(CFLAGS) $< -o Main-$#
clean-%:
rm Main-$*
Notice that %-clean has a shorter stem, and therefor takes precedence over the % if the make target starts with clean-.

proper usage of makefile

So, I'm trying to understand makefiles. At this moment I have a project with some modules, which are more or less non-dependent on each others.
My directory tree is like this:
root/
- Source/ <-- referenced as $(INPUTPATH)
- Build/ <-- referenced as $(BUILDPATH)
- Release/ <-- referenced as $(OUTPUTPATH)
- Makefile
I want to have the source (.cpp/.h) on the Source/, the objects on the Build/, and the executable on the Release/*.
So, my idea was to have several different targets, and use them like this:
all: maps auxiliars methods
#echo "linking...";\
$(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o ${OUTPUTPATH}/MainProgram
dependency1: $(INPUTPATH)/foo.cpp
#echo "compiling ArbPrecision...";\
cd ${BUILDPATH};\
$(CC) $(CFLAGS) $(CINCLUDE) -c ../$?
dependency2: dependency1 $(INPUTPATH)/bar.cpp
#echo "compiling saddleConstructor...";\
cd ${BUILDPATH};\
$(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/bar.cpp
maps: dependency2 $(INPUTPATH)/*Map.cpp
#echo "compiling maps...";\
cd ${BUILDPATH};\
$(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/*Map.cpp
... (auxiliars and methods)
The $CINCLUDE and CFLAGS are just compiler stuff like headers and external libs.
Everything works almost perfect: on every target, it asks for other target's dependencies, and for the *cpp on the source. If this does not exist, it calls the target and compiles the *cpp. The executable is created without errors.
However, if I call the "make" twice, the time it takes to compile is the same for the first and second time, even if I don't make any changes on the source. So, apparently, I'm not putting the dependencies right.
Can anyone point me the right direction to perform this compilation? I'm doing something wrong and I'm not getting what it is.
Thanks,
Jorge
Make expects to operate off of files. For each rule, it checks to see if the target file named by that rule (1) exists and (2) is up to date (i.e., modified after any of its dependencies). If the file is not up to date, then it executes the rule to bring it up to date.
Therefore, as your makefile is currently written, when you run make, Make does the following:
all is the first rule, so if you don't specify any arguments, make processes the all rule.
No file named all exists, so the all rule needs to be executed.
all depends on the dependency1 rule. No file named dependency1 exists, so the dependency1 rule needs to be executed.
dependency1 depends on the dependency2 rule. No file named dependency2 exists, so the dependency2 rule needs to be executed.
What you instead want is something similar to the following:
OBJS := foo.o bar.o Map.o
all: $(OUTPUTPATH)/MainProgram
$(OUTPUTPATH)/MainProgram: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o $(OUTPUTPATH)/MainProgram
%.o: %.cpp
$(CC) $(CFLAGS) $(CINCLUDE) $< -c $#
.PHONY: all
Note the following:
Since Make operates on files, rules' targets and dependencies are listed by filename wherever possible.
Rather than listing the .cpp files individually, an pattern rule is used to build each .o file. Within the pattern rule, the $< and $# automatic variables are used to specify the first prerequisite (file) and the target (file), respectively.
Make echoes its commands by default, so there's no need to echo yourself.
For GNU Make, all is listed as a phony target, to keep Make from looking for a file named all.

Makefile - Dependency generation

I am trying to create a makefile that automatically compiles and links my .cpp files into an executable via .o files. What I can't get working is automated (or even manual) dependency generation. When i uncomment the below commented code, nothing is recompiled when i run make build. All i get is make: Nothing to be done for 'build'., even if x.h (or any .h file) has changed. I've been trying to learn from this question: Makefile, header dependencies, dmckee's answer, especially. Why isn't this makefile working?
Clarification: I can compile everything, but when I modify any header file, the .cpp files that depend on it aren't updated. So, if I for instance compile my entire source, then I change a #define in the header file, and then run make build, and I get Nothing to be done for 'build'. (when I have uncommented either commented chunks of the below code).
CC=gcc
CFLAGS=-O2 -Wall
LDFLAGS=-lSDL -lstdc++
SOURCES=$(wildcard *.cpp)
OBJECTS=$(patsubst %.cpp, obj/%.o,$(SOURCES))
TARGET=bin/test.bin
# Nothing happens when i uncomment the following. (automated attempt)
#depend: .depend
#
#.depend: $(SOURCES)
# rm -f ./.depend
# $(CC) $(CFLAGS) -MM $^ >> ./.depend;
#
#include .depend
# And nothing happens when i uncomment the following. x.cpp and x.h are files in my project. (manual attempt)
#x.o: x.cpp x.h
clean:
rm -f $(TARGET)
rm -f $(OBJECTS)
run: build
./$(TARGET)
build: $(TARGET)
$(TARGET): $(OBJECTS)
#mkdir -p $(#D)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
obj/%.o: %.cpp
#mkdir -p $(#D)
$(CC) -c $(CFLAGS) $< -o $#
This may take a few iterations.
1) I can't reproduce your results from your first approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). This:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ >> ./.depend;
include .depend
seems to work as intended. I suggest you try $(info sources: $(SOURCES)) to verify that that variable contains the filenames you think it does.
2) I can't reproduce your results from your second approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). You tried x.o: x.cpp x.h when the first approach was commented out, is that right?
EDIT:
Let's concentrate on x.o. Does it contain #include "x.h"? When you uncomment the first section and make x.o, does Make produce (or modify) .depend? Is there a line in .depend that pertains to x.o, and if so what is it? If you then modify x.h and then make x.o, what does Make do?
You resolve only one kind of dependency with $(CC) -MM. There are various others like changed command options (e.g. -DDO_SOMETHING_ELSE), or a different set of symbols exported by a library. Traditional makes offer you lots of fun debugging inconsistent executables!
That's where makepp comes in. Dependencies are detected automatically. It not only rebuilds targets whenever any kind of dependency warrants this. It even chains everything together and builds what is needed from bottom up. I.e. if your linker has a -lmystuff option and you have a rule to build libmystuff.so or .a, that's all it takes, it will get built in time. Likewise you can include files that don't even exist yet — impossible with your solution.