How to run the targets parallely in makefile - makefile

I have a makefile :
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
%.o: %.cpp
$(CC) $(CFLAGS) $(<F) -o $#
When we execute this, we can see that the targets main.o, hello.o, factorial.o are running in serial, as these are independent of each, can we make them to run in parallel.
g++ -c -Wall main.cpp -o main.o
g++ -c -Wall hello.cpp -o hello.o
g++ -c -Wall factorial.cpp -o factorial.o
If yes, please help me

(Answered in a comment. See: Empty InfoWindow when Marker is clicked )
#Wintermute wrote:
Call make -j $number, where $number is the maximum number of processes you want it to spawn in parallel.
See also the documentation here: https://www.gnu.org/software/make/manual/html_node/Parallel.html#Parallel

Related

GNU makefiles remaking existing targets

I have a simple makefile on my machine:
# Compiler: g++ for C++ source files
CC = g++
# Compiler flags:
CFLAGS = -std=c++14 -Wall -Wextra -pedantic -O0 -c
foo.o: foo.cpp
$(CC) $(CFLAGS) $?
bar.o: bar.cpp
$(CC) $(CFLAGS) $?
foobar: foo.o bar.o
$(CC) -o $# $?
When I run make it remakes each target, even if it already exists. I want the makefile to ignore existing targets. What am I doing wrong?
Doing this fixed my problem:
# Compiler: g++ for C++ source files
CC = g++
# Compiler flags:
CFLAGS = -std=c++14 -Wall -Wextra -pedantic -O0 -c
all: foo.o bar.o foobar
foo.o: foo.cpp
$(CC) $(CFLAGS) $<
bar.o: bar.cpp
$(CC) $(CFLAGS) $<
foobar: foo.o bar.o
$(CC) -o $# $^
and also
touch makefile

Compiling with nvcc and g++

I'm using Nvidia's nvcc compiler to compile a .cpp file which will contain device code (but only contains host code now). The program I am using is written in C and C++ and uses gcc/g++ to compile with and g++ is used to link the final executable together. Originally, when I run my program using -Ofast, it runs in about 2 seconds, but I factored in nvcc to compile 1 .cpp file and the rest with gcc/g++, have g++ link it together, the program takes about 8 seconds to run. If I compile more .cpp files with nvcc, it slows down even more (~10 seconds). I tried adjusting my make file to compile everything with nvcc but I received too many errors from the C code. Only the C++ code seems to be able to run without errors when compiled with nvcc. Does nvcc not optimise the host code? Why does this happen? What is the best way to structure the program?
Makefile
CC = gcc
CCPP = g++
NVCC = /vol/cuda/8.0.61/bin/nvcc
#preprocessor defines
DEFINES = -DUSE_ZLIB
OPTFLAGS = -Ofast
#CFLAGS = -ansi -pedantic -Wall -Werror -fPIC
#CFLAGS = -ansi -pedantic -Wall -fPIC
CFLAGS = -ansi $(OPTFLAGS)
NVFLAGS = -x c++ -Wno-deprecated-gpu-targets -ccbin g++
NVLINKFLAGS = -L/vol/cuda/8.0.61/lib64/ -lcuda -lcudart
#NVLINKFLAGS += -L/vol/cuda/8.0.61/lib -lcuda -lcudart
CPPFLAGS = $(OPTFLAGS) -I./include $(DEFINES)
LINKFLAGS = -lz
all : simple
objs = src/tourtre.o \
src/ctArc.o \
src/ctBranch.o \
src/ctComponent.o \
src/ctNode.o \
src/ctQueue.o \
src/ctNodeMap.o \
examples/simple/obj/Data.o \
examples/simple/obj/Mesh.o \
examples/simple/obj/main.o
simple : $(objs)
$(CCPP) $(CPPFLAGS) -o simple $^ $(LINKFLAGS) $(NVLINKFLAGS)
src/tourtre.o : src/tourtre.c include/tourtre.h src/ctMisc.h include/ctArc.h include/ctNode.h src/ctComponent.h include/ctNode.h src/ctQueue.h src/ctAlloc.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctArc.o : src/ctArc.c include/tourtre.h src/ctMisc.h include/ctArc.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctBranch.o : src/ctBranch.c include/tourtre.h src/ctMisc.h include/ctBranch.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctComponent.o : src/ctComponent.c include/tourtre.h src/ctMisc.h src/ctComponent.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctNode.o : src/ctNode.c include/tourtre.h src/ctMisc.h include/ctNode.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctQueue.o : src/ctQueue.c include/tourtre.h src/ctMisc.h src/ctQueue.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
src/ctNodeMap.o : src/ctNodeMap.c src/ctNodeMap.h include/ctNode.h src/ctQueue.h src/sglib.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
examples/simple/obj/Data.o: examples/simple/src/Data.cpp examples/simple/src/Data.h examples/simple/src/Global.h
$(CCPP) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
examples/simple/obj/Mesh.o: examples/simple/src/Mesh.cpp examples/simple/src/Data.h examples/simple/src/Global.h examples/simple/src/Mesh.h
$(NVCC) $(NVFLAGS) -c $< -o $#
examples/simple/obj/main.o: examples/simple/src/main.cpp examples/simple/src/Data.h examples/simple/src/Global.h examples/simple/src/Mesh.h
$(CCPP) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
clean :
-rm -rf src/*.o examples/simple/obj/*.o doc/html
Add -Xcompiler -ansi -Xcompiler -Ofast to NVFLAGS so that the host compiler gets the same (optimization) flags from nvcc as when run directly.

Loop through list of files in Makefile

I compiling my C source files with this code:
CC=clang -std=c11
CFLAGS=-Wall -g
ASSEMBLY=-S -masm=intel
OPTIMIZE=-Ofast
FOLDER_SRC=./src/
FOLDER_BIN=./bin/
FOLDER_ASSEMBLY=./ass/
clean:
rm -f \
$(FOLDER_BIN)1.1-hello $(FOLDER_ASSEMBLY)1.1-hello \
$(FOLDER_BIN)1.2-fahrenheit $(FOLDER_ASSEMBLY)1.2-fahrenheit \
$(FOLDER_BIN)1.2-fahrenheit-floating $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
all:
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_BIN)1.1-hello
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_BIN)1.2-fahrenheit
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_BIN)1.2-fahrenheit-floating
assembly:
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_ASSEMBLY)1.1-hello
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
I try to implement some kind of loop to write less. I added this code, but it just generating errors:
FILENAME_SRC := $(wildcard $(FOLDER_SRC)*.c)
FILENAME_BUILD := $(patsubst $(FOLDER_SRC)%.c,%,$(FILENAME_SRC))
echo : $(FILENAME_SRC)
#echo $^
#echo $(FILENAME_BUILD)
build : $(FILENAME_SRC)
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $(FILENAME_BUILD)
make echo printing this to the console:
$ make echo
src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c
1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
make build command generating this error:
$ make build
clang -std=c11 -Wall -g -Ofast src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c -o 1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
clang.exe: error: no such file or directory: '1.1-hello'
clang.exe: error: no such file or directory: '1.2-fahrenheit-floating'
make: *** [Makefile:21: build] Error 1
I want the expected output to look like when I do make all:
$ make all
clang -std=c11 -Wall -g -Ofast ./src/1.1-hello.c -o ./bin/1.1-hello
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit.c -o ./bin/1.2-fahrenheit
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit-floating.c -o ./bin/1.2-fahrenheit-floating
Final solution
CC := clang -std=c11
GCC := gcc -std=c11
CFLAGS := -Wall -g
ASSEMBLY := -Wall -S -masm=intel
OPTIMIZE := -O3 -march=native
SRC := $(wildcard src/*.c)
BIN := $(patsubst src/%.c,bin/%,$(SRC))
ASS := $(patsubst src/%.c,ass/%,$(SRC))
clean:
rm -f bin/* ass/*
build: $(BIN)
$(BIN): bin/%: src/%.c
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $#
assembly: $(ASS)
$(ASS): ass/%: src/%.c
$(CC) $(ASSEMBLY) $(OPTIMIZE) $^ -o $#
Really sorry for the clean ass/* though, it cannot be called assembly because the similar folder name in the project.
Your all rule needs to look something like
CC := clang
CFLAGS := -std=c11 -Wall -g -Ofast
targets := bin/1.1-hello bin/1.2-fahrenheit bin/1.2-fahrenheit-floating
.PHONY: all
all: $(targets)
$(targets): bin/%: src/%.c
$(LINK.c) $^ $(LDLIBS) -o $#

Makefile not prompting compiler to use optimization flag

I have a simple makefile that I am using in bash to compile a C++ program and its associated .h files, not every .h file has a .cpp file associated with it. I wrote a makefile where each dependency was called out explicitly and the CFLAG macro was used for each specific dependency and it did compile with the -O3 flag and ran nearly 3 times faster. However, when I use this simpler, but somewhat more sophisticated makefile, it does not compile with the -O3 flag even though it is clearly included with the CFLAG macro. Can someone point out to me what I am missing, I would greatly appreciate it.
OBJS = main.o Output_Files.o Calendar.o Random_Number_Generator.o \
Algorithm.o Statistics.o
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CC=c++
CFLAGS=-c -Wall -O3
all: economics
%o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $# $<
economics: $(OBJS)
$(CC) $(OBJS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CC) $(CFLAGS) main.cpp
The rule:
%o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $# $<
should be written with an extra dot:
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $<
Also, you don't want $# in the command line, or (if you must have it) you need to prefix it with -o.
The makefile is not using the faulty rule but instead uses the default rule for building C++ object files, and that most probably doesn't use $(CFLAGS) but uses $(CXXFLAGS) instead.
CC is the macro for the C compiler, not the C++ compiler. Normally, that is CXX. Also, the rule to build economics actually creates a.out and not economics.
I'd prefer it if you wrote:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
…
economics: $(OBJS)
$(CC) -o $# $(OBJS)
Putting it all together gives this new.makefile:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CC = c++
CFLAGS = -c -Wall -O3
all: economics
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $<
economics: $(OBJS)
$(CC) -o $# $(OBJS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CC) $(CFLAGS) main.cpp
Running make -n with the old makefile
$ make -n -f old.makefile
c++ -c -Wall -O3 main.cpp
c++ -c -o Output_Files.o Output_Files.cpp
c++ -c -o Calendar.o Calendar.cpp
c++ -c -o Random_Number_Generator.o Random_Number_Generator.cpp
c++ -c -o Algorithm.o Algorithm.cpp
c++ -c -o Statistics.o Statistics.cpp
c++ -o economics main.o Output_Files.o Calendar.o Random_Number_Generator.o Algorithm.o Statistics.o
$
Running make -n with the new makefile
$ make -n -f new.makefile
c++ -c -Wall -O3 main.cpp
c++ -c -Wall -O3 Output_Files.cpp
c++ -c -Wall -O3 Calendar.cpp
c++ -c -Wall -O3 Random_Number_Generator.cpp
c++ -c -Wall -O3 Algorithm.cpp
c++ -c -Wall -O3 Statistics.cpp
c++ -o economics main.o Output_Files.o Calendar.o Random_Number_Generator.o Algorithm.o Statistics.o
$
This is still an abnormal way of writing the make rules on a number of grounds, one being the $(CC) vs $(CXX) change. Normally, the -c option is not included in $(CFLAGS) or $(CXXFLAGS). Normally, you include $(CFLAGS) or $(CXXFLAGS) in the link line too (because some of the flags might affect linking). Often, you need libraries and related flags in the linker line too.
This leads to a more orthodox naming convention:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CXX = c++
CXXFLAGS = -Wall -O3
LDFLAGS =
LDLIBS =
all: economics
%.o: %.cpp $(DEPS)
$(CXX) -c $(CXXFLAGS) $<
economics: $(OBJS)
$(CXX) -o $# $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CXX) -c $(CXXFLAGS) main.cpp

CFLAGS are ignored in Makefile

I am using the following makefile to build my project:
CC = /usr/bin/g++
CFLAGS = -Wall -pedantic -std=c++0x
LDFLAGS =
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: $(OBJ)
$(CC) $(CFLAGS) -o pnm $(OBJ) $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c $<
As I run make I get the following error:
/usr/include/c++/4.9.1/bits/c++0x_warning.h:32:2: error: #error This
file requires compiler and library support for the ISO C++ 2011
standard. This support is currently experimental, and must be enabled
with the -std=c++11 or -std=gnu++11 compiler options.
As I can read from the following line, the CFLAGS are not properly included, but I have no idea what I am doing wrong:
g++ -c -o main.o main.cpp
Also tried -std=c++11 and -std=gnu++11, without any results. Any ideas?
If I run make -Bn, I get:
g++ -c -o main.o main.cpp
g++ -c -o pnmhandler.o pnmhandler.cpp
g++ -c -o pixmap.o pixmap.cpp
g++ -c -o color.o color.cpp
/usr/bin/g++ -Wall -pedantic -std=c++0x -o pnm main.o pnmhandler.o pixmap.o color.o
EDIT: Replacing the rule %.o: %.c with %.o: %.cpp fixes my problem.
The reason you see
g++ -c -o main.o main.cpp
is that Make is invoking its standard rule to create the object file:
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
The command expands to
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
Instead of setting CC and CFLAGS in your makefile, you should set CXX and CXXFLAGS, which are meant for C++ rather than C. That allows the built-in rule above to work for you, and then you just need to make sure the right linker is used, e.g. with
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
You also don't need the %.o: %.c rule, as you have no C sources.
Complete Makefile:
CXX = /usr/bin/g++
CXXFLAGS = -Wall -pedantic -std=c++0x
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
clean::
$(RM) pnm
.PHONY: clean

Resources