As a follow-up question from here: My Makefile will do the linking, even if nothing is changed in the code. Why? How can I avoid that behaviour, so that make won't do anything if the code has not changed?
OBJS = main_no_mkl.o
SOURCE = main_no_mkl.cpp
HEADER = IO.h
OUT = test
CXX = ../../mpich-install/bin/mpic++
CXXFLAGS = -I../../intel/mkl/include -Wl,--start-group -Wl,--end-group -lpthread -lm -ldl -Wall
LDFLAGS = ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a -Wl,--start-group ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a ../../intel/mkl/lib/intel64/libmkl_sequential.a -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread -lm -ldl
all: $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
# create/compile the individual files >>separately<<
main_no_mkl.o: main_no_mkl.cpp
$(CXX) -c main_no_mkl.cpp $(CXXFLAGS)
.PHONY : all
The problem is your all target. It doesn't generate an all (and is marked .PHONY as well) file. Check this answer for a reminder about .PHONY. (You are violating the second Rule of Makefiles.)
So the second/etc time you run make (assume the .PHONY marking wasn't present) make would look for an all file, not find it, and assume it must need to create it again.
With .PHONY you short-circuit that file-finding logic and make just always assumes it needs to run the recipe again.
So, essentially, you've told make to always run the linking step so make does that.
Use this instead to fix that problem.
all: $(OUT)
$(OUT): $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
For the record running make -d and reading through the output would have pointed this out to you.
The objects are really the dependencies of your output, and your "all" target should depend on the output(s). So you should do something like this instead:
all: $(OUT)
$(OUT): $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
Related
I am trying to write a makefile that can create one executable per main function.
I have a list of files: main1.cpp, main2.cpp, and main3.cpp. They each contain an int main() function. Obviously I can't build these into one exec, which is not the goal here, so how can I build each one of these into its own executable? This is one solution:
main1: main1.cpp
$(CC) -o $# $^
main2: main2.cpp
$(CC) -o $# $^
main3: main3.cpp
$(CC) -o $# $^
But there MUST be a better way to do this. Is there some type of looping feature to makefiles that will make this process easier? Like a for loop?
A mixture of wildcard, patsubst and static pattern rules, plus the standard make variables for C++ compilation and linking:
SRCS := $(wildcard main*.cpp)
EXES := $(patsubst %.cpp,%,$(SRCS))
$(EXES): %: %.cpp
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $< $(LDLIBS)
But as make knows already how to make all this you could as well get rid of your Makefile and just type make main1...
While it's not a very sophisticated makefile, your solution is fine for three simple programs. You could make it more generic and support building all three targets at the same time with an "all" target.
all: main1 main2 main3
main1: main1.cpp
$(CC) -o $# $^
main2: main2.cpp
$(CC) -o $# $^
main3: main3.cpp
$(CC) -o $# $^
I have multiple source files in a directory, which some are responsible for a main executable, and some are responsible for a shared library, which then in turn is needed for the main executable. Thus I wrote the makefile in the following way:
CC=gcc
CXX=g++
CFLAGS=-I$(DIR) -fPIC -c -fopenmp
CXXLFLAGS=-I$(DIR) -fopenmp -O3 -g -march=native -std=gnu++17 -fPIC -c
CXXFLAGS=-I$(DIR) -fopenmp -O3 -g -march=native -std=gnu++17 -c
LDFLAGS=-lfftw3 -lgomp -lm -larmadillo -lpthread -lX11 -lboost_system -lboost_program_options -L/opt/intel/mkl/lib/intel64 -lmkl_rt
LDMAINFLAGS=-lfftw3 -lgomp -lm -larmadillo -lpthread -lX11 -lboost_system -lboost_program_options -L/opt/intel/mkl/lib/intel64 -lmkl_rt -lpulse_propagation
LIBSOURCES=source/image_processing.cpp source/pulse_propagation.cpp
LIBOBJECTS=source/image_processing.o source/pulse_propagation.o
MAINSOURCES=source/fftw.cpp source/fftw++.cc
MAINOBJECTS=source/fftw.o source/fftw++.o
EXECUTABLE=fftw
LIBRARY=libpulse_propagation.so
.PHONY: default all clean
default: all
all: $(LIBRARY) main
main: $(LIBRARY) $(MAINOBJECTS)
$(CXX) $(LDFLAGS) $(MAINOBJECTS) -o $(EXECUTABLE)
$(LIBRARY): $(LIBOBJECTS)
$(CXX) $(LDFLAGS) -shared $^ -o $#
$(LIBOBJECTS): $(LIBSOURCES)
$(CXX) $(CXXLFLAGS) $^ -o $#
$(MAINOBJECTS): $(MAINSOURCES)
$(CXX) $(CXXFLAGS) $^ -o $#
clean_compile:
rm -f source/*.o
clean:
rm -f source/*.o $(EXECUTABLE) $(LIBRARY)
with everything labeled with a MAIN belonging to the main executable and everything else to the library. I would like to loop over the files in LIBSOURCES/MAINSOURCES and compile each of them. I would prefer if I do not have to use the .cpp.o:-macro, after there are different flags depending if it is a library file or a main file. I tried using $<, which executed the compilation twice (ok), but always used the first value from the variable list. When using $^ instead, both files are used at once, also resulting in an error. How could I else do that?
Your source/fftw++.cc instead of source/fftw++.cpp makes everything uselessly complex. If you can rename it, then the following should do what you want:
$(LIBOBJECTS): CXXFLAGS := $(CXXLFLAGS)
$(LIBOBJECTS) $(MAINOBJECTS): %.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
The first line defines the value of variable CXXFLAGS for the $(LIBOBJECTS) targets. The following rule is a static pattern rule that translates into as many rules with one target and one prerequisite only. It is completely different from your rules that declares all source files of one kind as prerequisites of all corresponding object files. Not what you want normally.
If you cannot rename source/fftw++.cc you can split your sources and objects lists:
MAINCPPSOURCES=source/fftw.cpp
MAINCCSOURCES=source/fftw++.cc
MAINCPPOBJECTS=source/fftw.o
MAINCCOBJECTS=source/fftw++.o
$(LIBOBJECTS): CXXFLAGS := $(CXXLFLAGS)
$(LIBOBJECTS) $(MAINCPPOBJECTS): %.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
$(MAINCCOBJECTS): %.o: %.cc
$(CXX) $(CXXFLAGS) $< -o $#
Finally, it would probably be better (easier to maintain) if you were computing what can be, instead of hard-wiring it in your Makefile:
MAINCPPOBJECTS = $(patsubst %.cpp,%.o,$(MAINCPPSOURCES))
MAINCCOBJECTS = $(patsubst %.cc,%.o,$(MAINCCSOURCES))
...
I'm brushing up on C++ by completing many small programs, each contained in a single cpp file. I also want to learn a little bit more about Makefiles, and decided to write a Makefile that will compile all of my little programs and produce an executable per program. With my current Makefile, I have to:
Append the name to the end of "BINARIES"
Copy the repeated target and replace the target name with the binary name
How can I edit this Makefile to be even more generic, so that I can simply append the name of my new program to the end of "BINARIES" and not have to continue to copy and paste the repeated targets?
BIN=./bin/
SOURCE=./src/
CXX=g++
CXXFLAGS=-g -c -Wall
BINARIES=sums-in-loop sum-in-loop sum-of-two
RM=rm -f
all: sums-in-loop sum-in-loop sum-of-two
sums-in-loop:
$(CXX) $(CXXFLAGS) $(SOURCE)$#.cpp -o $(BIN)$#
sum-in-loop:
$(CXX) $(CXXFLAGS) $(SOURCE)$#.cpp -o $(BIN)$#
sum-of-two:
$(CXX) $(CXXFLAGS) $(SOURCE)$#.cpp -o $(BIN)$#
clean:
$(RM) $(BIN)*
The usual way is to use pattern rules:
BIN=bin
SOURCE=src
CXX=g++
CXXFLAGS=-g -Wall
BINARIES=sums-in-loop sum-in-loop sum-of-two
RM=rm -f
all: $(addprefix $(BIN)/,$(BINARIES))
$(BIN)/%: $(SOURCE)/%.cpp
$(CXX) $(CXXFLAGS) $< -o $#
clean:
$(RM) $(BIN)/*
With loops in Makefile, you can do something like :
$(foreach bin,$(BINARIES),$(CXX) $(CXXFLAGS) $(SOURCE)$(dir).cpp -o $(BIN)$dir;)
You can find some info --> http://www.gnu.org/software/make/manual/make.html#Foreach-Function
I am compiling some project with dependency so i won't have to recompile each time, but when i am adding -Dsome_flags to my CFLAGS, it is not recompiling.
dep: $(CPPS)
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
i add to my CFLAS -DDEBUG_FLAG and it forces me to do make clean and make instead of make.
It won't recompile because you don't have the makefile itself listed as a dependency.
dep: $(CPPS) Makefile
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
That said, if you're feeding in make flags from the command line (e.g. CFLAGS=-O3 make all), make has no way of detecting that you've changed those and forcing a full build.
The simplest, in my opinion, would be to do a make clean and then a make. This is of course assuming that you want all source files to be recompiled due to the change in compiler flags. But you seem to not like this method.
If you want to modify the makefile, you can add the name of your makefile to every rule for compiling source files, for example:
somefile.o : somefile.cpp <makefile_name>
$(CC) -c $(CFLAGS) somefile.cpp -o somefile.o
or
%.o : %.c <makefile_name>
$(CC) -c $(CFLAGS) somefile.cpp -o somefile.o
Given the size of the project, and the number of rules involved, doing a make clean; make may be the easiest and fastest method. However, as always, you mileage my vary.
Just my $0.02 worth, hope it helps
T.
Makefile looks for changes based on the data it has. Your Makefile states the only dependencies are defined under $(CPPS).
dep: $(CPPS)
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
So the make tracks the changes only within the given list, i.e., $(CPPS). So the resolution is:
dep: $(CPPS) Makefile
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
For complete but non-complex example, here is my Makefile for a helloworld program:
OBJS = helloworld.o
default: hw
%.o: %.c Makefile
gcc -c $< -o $#
hw: $(OBJS)
gcc $(OBJS) -o $#
clean:
-rm -f $(OBJS) hw
Everytime I change my makefile it gets recompile! :)
I would appreciate if anyone could help me with the Makefile error. I would like to compile a C++ application into a shared library and place the compiled object *.o files in ./sobjs directory like below. I followed several examples to do this, however I still have the problem to get this correct compilation and linker.
Makefile:
OBJS = a1.o a2.o a3.o a4.o a5.o
objects = sobj/$(OBJS)
all: $(objects)
$(CXX) $(CXX_FLAGS) $(objects) -shared -o libname.so
$(objects) : | sobjs
sobjs:
#mkdir -p $#
sobjs/%.o: %.cpp
#echo $<
$(CXX) -fPIC -c -o $# $< $(CXX_FLAGS) $(MY_FLAGS) $(INCLUDE_DIRS)
I made a mistake. Replace this
objects = sobj/$(OBJS)
with this
objects = $(patsubst %.o, sobjs/%.o,$(OBJS))
and it will now compile files correctly.