Generate all targets in makefile - makefile

I have Makefile:
INC=-I/usr/lib/boost_1_61_0
PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)
# location of the Boost Python include files and library
MINIREADER_INC = ./../../hdr
BOOST_INC = /usr/lib/boost_1_61_0
BOOST_LIB = /usr/lib/boost_1_61_0/stage/lib
TARGET = LoggerTestModule
$(TARGET).o: $(TARGET).cpp
g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -I$(MINIREADER_INC) -fPIC -c $(TARGET).cpp --std=c++14 -g3
$(TARGET).so: $(TARGET).o
g++ -shared -Wl,--export-dynamic $(TARGET).o ../../Release/src/Logger.o -L$(BOOST_LIB) -lboost_python -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) -o $(TARGET).so --std=c++11 -g3
When running make -f Makefile only object file gets generated, how I can change makefile to generate both "object and library file"?
Thanks

Add a phony target and put it before the others such that it is the default goal:
...
TARGET = LoggerTestModule
.PHONY: all
all: $(TARGET).o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -I$(MINIREADER_INC) -fPIC -c $(TARGET).cpp --std=c++14 -g3
...
Explanations: all is the default goal (first non-special target in Makefile) and depends on $(TARGET).o $(TARGET).so. So, we invoking make without specifying a goal, it is all that will be built and all its pre-requisites will be rebuilt if needed. Declaring it as a pre-requisite of the .PHONY special target tells make to rebuild it, even if, by accident, a file named all exists.

Get rid of the rule for the object file, make already knows how to build it. You should probably also restructure your vars to align them with the built-in rule for linking, which you can then recycle
TARGET := LoggerTestModule
PYTHON_VERSION := 2.7
PYTHON_INCLUDE := /usr/include/python$(PYTHON_VERSION)
MINIREADER_INC := ./../../hdr
BOOST_INC := /usr/lib/boost_1_61_0
BOOST_LIB := /usr/lib/boost_1_61_0/stage/lib
CPPFLAGS := -I$(PYTHON_INCLUDE) -I$(MINIREADER_INC) -I$(BOOST_INC)
CXXFLAGS := -fPIC -std=c++14 -g3
LDFLAGS := -L$(BOOST_LIB) -L/usr/lib/python$(PYTHON_VERSION)/config
LDLIBS := -lboost_python -lpython$(PYTHON_VERSION)
$(TARGET).so: CC := $(CXX)
$(TARGET).so: LDFLAGS += -shared -Wl,--export-dynamic
$(TARGET).so: $(TARGET).o ../../Release/src/Logger.o
$(LINK.o) $^ $(LDLIBS) -o $#

Related

CXXFLAGS not being appended in makefile

I have a makefile that I want to be able to produce both a release build and a debug build. When I just run:
make
I want the CXXFLAGS to be:
-std=c++11 -Isrc/includes -c -Os
and when I run
make debug
I want the CXXFLAGS to be
-std=c++11 -Isrc/includes -c -g
I am trying to do this through he use of phony targets and appending the extra flags to the CXXFLAGS variable, however these extra flags are never being appended. why is it that make debug still produces:
g++ -std=c++11 -Isrc/includes -c src/file.cpp -o build/obj/file.o
and not the expected
g++ -std=c++11 -Isrc/includes -c -g src/file.cpp -o build/obj/file.o
when it is run?
contents of makefile:
vpath %.cpp src/macro
vpath %.cpp src/data_types
vpath %.hpp src/includes
vpath %.cpp src
CXX := g++
CXXFLAGS := -std=c++11 -Isrc/includes -c
LXX = g++
LXXFLAGS :=
BUILDDIR := build
OBJDIR := $(BUILDDIR)/obj
SRCS := $(notdir $(shell find -name '*.cpp'))
OBJS := $(patsubst %.cpp, $(OBJDIR)/%.o, $(SRCS))
all: release aval
aval: builddir $(OBJS) $(SRCS)
$(LXX) $(LXXFLAGS) $(OBJS) -o $(BUILDDIR)/aval
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) $^ -o $#
.PHONY: release
release: CXXFLAGS += -Os
release: LXXFLAGS += -s -Os
.PHONY: debug
debug: clean db aval
.PHONY: db
db: CXXFLAGS += -g
.PHONY: builddir
builddir:
#mkdir -p $(OBJDIR)
.PHONY: clean
clean:
#rm -f -r build/obj/*.o
#rm -f build/avalanche
the issue with what you are doing is that you are editing the CXXFLAGS in the dependency list of a rule which won't work because of the way the make file is parsed.
Another way - and really easy, and saves you recursively calling make - which I don't see as particularly evil - but some do. Its certainly less complicated this way I find.
CXXFLAGS = defaults
ifneq (,$(findstring release,$(MAKECMDGOALS)))
CXXFLAGS += release
else ifneq (,$(findstring debug,$(MAKECMDGOALS)))
CXXFLAGS += debug
endif
all:
#echo CXXFLAGS = $(CXXFLAGS)
# Rules for release / debug. The `; #:` part means the body of the rule is empty (do nothing). It just "calls" the dependency rule `all`.
release: all ; #:
debug: all ; #:
So here we are looking at the command goals and "parsing them" to look for your options and add to the flags.
We also need rules for debug and release to call the build rule (which I am calling all for the moment).
Here is the output:
admin#osboxes:~/sandbox/flags$ make
CXXFLAGS = defaults
admin#osboxes:~/sandbox/flags$ make release
CXXFLAGS = defaults release
admin#osboxes:~/sandbox/flags$ make debug
CXXFLAGS = defaults debug
The approach you have chosen does not work, because
db: CXXFLAGS += -g
means that the variable CXXFLAGS is updated to include -g for the goal db, but no other goal. I.e. this change is not global like you intended it to be.
The following would be one way of implementing what you intended:
.PHONY: all release
# NOTE: must be first goal in Makefile to be default goal
all release:
$(MAKE) -f $(lastword $(MAKEFILE_LIST)) BUILD_CXXFLAGS="-Os" BUILD_LXXFLAGS="-s -Os" build
.PHONY: debug
debug:
$(MAKE) -f $(lastword $(MAKEFILE_LIST)) BUILD_CXXFLAGS="-g" BUILD_LXXFLAGS="-g" build
.PHONY: build
build: clean aval
CXX := g++
CXXFLAGS := $(BUILD_CXXFLAGS) -std=c++11 -Isrc/includes -c
LXX = g++
LXXFLAGS := $(BUILD_LXXFLAGS)
# ... and the rest of your original Makefile ...
With build implemented as a dummy echo, I get the following output from the above:
$ make -s
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'
$ make -s all
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'
$ make -s release
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'
$ make -s debug
CXX '-g -std=c++11 -Isrc/includes -c' LXX '-g'
BTW: you also need to add -g to LXXFLAGS, otherwise you won't get a debug binary.

Simplifying a makefile

I have written a scary-looking Makefile by copy/pasting suggestions from Stack Overflow. However, I have read that it might not be necessary to provide explicit compiler invocations so many times (for example, the -O3 flag is everywhere). How can I simplify this Makefile?
CFLAGS = -Weverything -Wno-padded -Wno-unused-parameter -Wno-unused-variable -Wno-sign-conversion
all: fianchetto.o util.o ttable.o movegen.o
clang -O3 $(CFLAGS) -D NDEBUG $^ -o fianchetto
debugf: fianchetto.o ttable.o movegen.o
clang -O3 $(CFLAGS) -g3 $^ -o fianchetto
clean:
rm *.o && rm *.gch & rm fianchetto && rm -rf fianchetto.dSYM
%.o: %.c
clang -O3 -c $(CFLAGS) $< -o $#
fianchetto.o: fianchetto.c
ttable.o: ttable.h ttable.c
movegen.o: movegen.h movegen.c
util.o: util.h util.c
I am mystified by a lot of the syntax, and would appreciate links or explanations of why simplifications work!
CFLAGS and defines (which should be in CPPFLAGS anyway) are useless when linking
You're reinventing make's built-in rules, make will automatically link a target if one of its dependencies is "target.o" (in this case fianchetto: fianchetto.o). Make also knows how to compile C source files (as long as the source and object path match), so your pattern rule is superfluous too.
The object prerequisites aren't necessary as both clang and GCC can generate dependencies for you with the -M set of flags.
Compiling release and debug builds in the same dir makes for a more simple makefile, although you will need to remember to clean the object files when switching.
By default make assigns cc to CC, and cc should be a link to your system's default compiler, so you might not even need the first line below
CC := clang
CPPFLAGS := -MMD -MP
CFLAGS := -Weverything -Wno-padded -Wno-unused-parameter -Wno-unused-variable -Wno-sign-conversion -O3
objs := fianchetto.o util.o ttable.o movegen.o
deps := $(objs:.o=.d)
.PHONY: all debugf clean
all: CPPFLAGS += -DNDEBUG
debugf: CFLAGS += -g3
all debugf: fianchetto
fianchetto: $(objs)
clean: ; $(RM) $(objs) $(deps) fianchetto fianchetto.dSYM
-include $(deps)

Compiling and linking fortran code with MakeFile using Intel compiler

I have a code that is about 8,000 lines and is contained in the same one big bigcode.f90 file. It compiles without problems from the command line with intel compiler with the options:
mpif90 bigcode.f90 -r8 -O2 -xHost -override-limits -o output.out
I want to split this large file into modules and link them using makefile. Below I am listing the makefile. (So here I have main.f90, and also 8 modules linked to it, such as modparams.o and other 7). So I just broke the bigcode.f90 into 9 files. The problem is that when I compile with the makefile, it complains about things like
subroutine ended with "end" statement instead of "end subroutine"
integer passed to reals
some name conflicts between variable names and subroutine names.
All these may well be bad style. However the original bigcode.f90 had all of these, and it did not prevent it from compiling at all. I want to first replicate the results between the bigcode.f90 and the split version - and then I will make other changes.
I also made a copy of this makefile without any OBJECTS to link (just the single bigcode.f90), and that also compiled without any complains. Could somebody help me understand why is there inconsistency about what the compiler complains when there is one file versus when there are several linked files?
# DEFAULT FLAGS
CFLAGS := -I$(CPATH) -I$(F90_MODULES_PATH)
F90 := mpif90
# ADD ALL LIBRARIES HERE (with -l$LIBRARY_NAME)
LDFLAGS := -llapack -v
# ADD ALL SOURCE FILES HERE (with .o extension)
OBJECTS := modparams.o
OBJECTS += modleeplex.o
OBJECTS += modutilsmain.o
OBJECTS += modecon.o
OBJECTS += modindirect.o
OBJECTS += modijutils.o
OBJECTS += modselectstata.o
OBJECTS += modfcn.o
# ADD ADDITIONAL COMPILER FLAGS HERE
CFLAGS += -fbounds-check
CFLAGS += -ffree-line-length-350
CFLAGS += -r8
CFLAGS += -O2
CFLAGS += -xHost
CFLAGS += -override-limits
# ADD ADDITIONAL MODULE FOLDERS HERE (with -I$PATH_TO_FOLDER)
F90_MODULES += -I.
all: main
main: main.f90 $(OBJECTS)
$(F90) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $< -o $#
%.o : %.f90
$(F90) -c $< $(CFLAGS) $(F90_MODULES) $(LDFLAGS) -o $#
clean:
rm -rf $(OBJECTS) *.mod
When I compile, I get the following, and then a long list of errors.
mpif90 -c modfcn.f90 -I/opt/intel/composer_xe_2013.5.192/mkl/include:/opt/intel/composer_xe_2013.5.192/tbb/include:/opt/intel/composer_xe_20 13.5.192/mkl/include:/opt/intel/composer_xe_2013.5.192/tbb/include -I -fbounds-check -ffree-line-length-350 -r8 -O2 -xHost -override-lim its -I. -llapack -v -o modfcn.o
ifort: command line warning #10006: ignoring unknown option '-ffree-line-length-350'
ifort: command line remark #10010: option '-pthread' is deprecated and will be removed in a future release. See '-help deprecated'
ifort version 13.1.3

How can I run a pattern rule within another rule in a makefile?

I am looking to write a makefile to automate the compiling of a project that I am working on where the files may, or may not, change in number. I also need to be able to quickly tell make to compile the files as a debug build or a release build (differentiated by a command line define). After some research, I came upon pattern rules and made one. Here is the code I have so far:
# Our folders
# ODIR - The .o file directory
# CDIR - The .cpp file directory
# HDIR - The .hpp file directory
ODIR = obj
CDIR = src
HDIR = inc
# Get our compiler and compiler commands out of the way
# CC - Our compiler
# CFNO - Our compiler flags for when we don't have an output file
# CF - Our compiler flags. This should be appended to any compile and should
# have the name of the output file at the end of it.
# OF - Object flags. This should be appended to any line that is generating
# a .o file.
CC = g++
CFNO = -std=c++11 -wall -Wno-write-strings -Wno-sign-compare -lpaho-mqtt3c -pthread -O2 -I$(HDIR)
CF = $(CFNO) -o
OF = -c
# Our project/output name
NAME = tls_test
# Set out Debug and Release settings, as well as any defines we will use to identify which mode we are in
# NOTE: '-D[NAME OF DEFINE]' is how you create a define through the compile commands
DEBUG = -DDEBUG -g
RELEASE = -DRELEASE
# Our two compile modes
# eval allows us to create variables mid-rule
debug:
$(eval DR = $(DEBUG))
release:
$(eval DR = $(RELEASE))
# Our compiling commands
all:
$(CC) $(CF) $(NAME) $(ODIR)/*.o
# NOTE: $# is the end product being created and $< is the first of the prerequisite
$(ODIR)/%.o: $(CDIR)/%.c
echo "$(CC) $(DR) $(OF) $(CF) $# $<"
The issue that I am having is with the order that I need things to run in. The command line call should tell make to use either debug or release, which sets a make variable, then call all. all should then run the pattern rule at the bottom before running the line currently in the all rule. So, how do I make a pattern rule a dependency and how do I call a rule from another rule?
Use target-specific variables
While not strictly necessary, separating your flags goes a long way in managing build options, you can then use target-specific variable appends to toggle the flags. While you're at it you might as well use the built-in variable names.
I've also added dependency generation (-MMD -MP) because it's always useful.
ODIR := obj
CDIR := src
HDIR := inc
SRCS := $(wildcard $(CDIR)/*.cpp)
OBJS := $(SRCS:$(CDIR)/%.cpp=$(ODIR)/%.o)
DEPS := $(OBJS:%.o=%.d)
CPPFLAGS := -I$(HDIR) -MMD -MP
CXXFLAGS := -std=c++11 -Wall -Wno-write-strings -Wno-sign-compare -pthread -O2
LDFLAGS := -pthread
LDLIBS := -lpaho-mqtt3c
NAME := tls_test
.PHONY: debug release clean
debug: CPPFLAGS+=-DDEBUG
debug: CXXFLAGS+=-g
release: CPPFLAGS+=-DRELEASE
debug release: $(NAME)
$(NAME): $(OBJS)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJS): $(ODIR)/%.o: $(CDIR)/%.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
clean: ; $(RM) $(NAME) $(OBJS) $(DEPS)
-include $(DEPS)

makefile for openmp by g++ ---- It is not working

I want to use a makefile for my code which is going to use openmp. My source files are compiled and linked without any error. But when I run it, it uses just one processor, even though I adjust their number by for instance export OMP_NUM_THREADS=2.
The makefile is shown in the following. I would be grateful if somebody could please help me.
Best
CPP_FILES := $(wildcard src/*.cpp)
OBJ_FILES := $(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
CC = g++
DEBUG = -g
INTEL=icc
ifeq ($(notdir $(CC)),$(INTEL))
CCFLAGS=-openmp -lm -lstdc++
else
CCFLAGS=-fopenmp -lm -lstdc++
endif
LD_FLAGS :=-fopenmp -Wall $(DEBUG)
#CC_FLAGS := -Wall -c $(DEBUG)
MAIN: $(OBJ_FILES)
$(CC) $(LD_FLAGS) -o $# $^
obj/%.o: src/%.cpp
$(CC) $(CC_FLAGS) -c -o $# $<
.PHONY: clean
clean:
rm -f $(OBJ_FILES) *.o
Your defined variable CCFLAGS doesn't match the variable you're using CC_FLAGS in the actual compilation rules. When you clean up and run make do the compilation lines actually show the flags you set being passed? I'd expect they shouldn't, unless the code you have here isn't a direct copy of what you're running.
For ease of debugging, could you copy and paste a terminal transcript showing the compilation and linking happening?

Resources