What is the difference between TARGET_ARCH and TARGET_MACH variables? - makefile

I am developing project for Cortex-M4 processor and my compiler flags include this:
-mlittle-endian -mthumb -mcpu=cortex-m4
Here is an excerpt from make database (make -p | grep -E '^(LINK|COMPILE)\.[cosS]\ ' | sort)):
COMPILE.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.s = $(AS) $(ASFLAGS) $(TARGET_MACH)
LINK.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
LINK.s = $(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)
I see that for assembler sources TARGET_MACH is used and for c-sources TARGET_ARCH is used but what is the difference and how to correctly specify this variables?

Found this: http://zoo.cs.yale.edu/classes/cs210/help/make.html says that TARGET_ARCH and TARGET_MACH are output of arch and mach for target system. If you search aforementioned utilities, you can find that on modern systems they corresponds to output of uname -m and uname -p. For my desktop they give me x86_64 and i386 correspondently.

Related

How to write a general pattern in makefile

I have multiple programs which share the same structure of compilation.
test_variance : test_variance.o
$(CPP) -o test_variance.exe $(CFLAGS) test_variance.o $(LIBDIR) $(LIBS)
test_variance_incremental: test_variance_incremental.o
$(CPP) -o test_variance_incremental.exe $(CFLAGS) test_variance_incremental.o $(LIBDIR) $(LIBS)
test_hyper: test_hyper.o
$(CPP) -o test_hyper.exe $(CFLAGS) test_hyper.o $(LIBDIR) $(LIBS)
test_hyper.o: test_hyper.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_hyper.cpp
test_variance_incremental.o: test_variance_incremental.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_variance_incremental.cpp
test_variance.o : test_variance.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_variance.cpp
So for compling .o, I can use the pattern
%.o: %.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c $<
I wonder if there is a general pattern for compling the executive. I've tried
TARGETS = test_variance test_variance_incremental test_hyper
$(TARGETS): $#.o
$(CPP) -o $#.exe $^ $(CFLAGS) $(LIBDIR) $(LIBS)
But Make tells me there is no input files and I think my usage of $# is wrong. Any advice?
You should use CC and CFLAGS for compiling C code, and CXX and CXXFLAGS for compiling C++ code. CPP (in make) is used for running the C preprocessor (only). The standard variable to hold libraries is LDLIBS.
If you use these variables then you don't even need to define your own rules at all: there are built-in rules in make that already know how to compile and link C++ programs. All you need is this:
TARGETS = test_variance test_variance_incremental test_hyper
all: $(TARGETS)
Anyway, if you want to write it explicitly you can write:
TARGETS = test_variance test_variance_incremental test_hyper
all: $(TARGETS)
% : %.o
$(CXX) -o $# $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
(you should definitely not name the target test_variance, but then have your link line build test_variance.exe: the target name and the file that the recipe builds must always be the same).

Why does my Makefile with pattern rules not create debugging symbols for main?

I am using this auto-generated Makefile with pattern rules, that I oviously do not understand yet. I want to create debuggins symbols and then debug main, but it doesn't work. There is a -g flag. Adding $(LDFLAGS) statement above after $(ODIR) does not print one as expcted.
IDIR =./include
CC=g++
CFLAGS = -I$(IDIR)
LDFLAGS = -g
ODIR=./
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c
$(CC) -c -o $# $< $(CFLAGS)
main: $(OBJ)
$(CC) $(LDFLAGS) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o
This is the terminal output
g++ -c -o Source.o Source.cpp
g++ -g -o Source Source.o -I./include
Your sources are C++ (.cpp) but your Makefile contains explicit instructions for building C files. Make is therefore falling back to its built in implicit rules.
Also note that by convention those rules use $(CXX) to refer to the C++ compiler, with $(CXXFLAGS) replacing $(CFLAGS), and the -I flag belongs in $(CPPFLAGS):
IDIR =./include
CPPFLAGS = -I$(IDIR)
CXXFLAGS = -g
ODIR=.
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.cpp
$(CXX) -c -o $# $(CPPFLAGS) $(CXXFLAGS) $<
main: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJ)
If you were to do away with the ODIR handling and use the conventional variable names you could do without the explicit .o: .cpp rule altogether.

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.

makefile & gcc -c compilation - how to name object files

I'm playing with makefile for class project.
(1) I need to create debug rule. But I don't know how to give specific names to object files that I need (do I need?) to create that debug-enabled executable.
(2)I assume file can be further reduced to fewer lines of code. Could you suggest how?
This is my makefile:
CC = gcc
CFLAGS = -Wall -Wextra -std=c11
OBJ = hospital.o parse.o structure.o description.o patientList.o diseaseList.o
DOBJ = hospital.dbg.o parse.dbg.o structure.dbg.o description.dbg.o patientList.dbg.o diseaseList.dbg.o
all: hospital
hospital: $(OBJ)
$(CC) $^ -o $#
hospital.o: hospital.c structure.h
$(CC) $(CFLAGS) -c $^
parse.o: parse.c parse.h
$(CC) $(CFLAGS) -c $^
structure.o: structure.c structure.h
$(CC) $(CFLAGS) -c $^
patientList.o: patientList.c patientList.h
$(CC) $(CFLAGS) -c $^
diseaseList.o: diseaseList.c diseaseList.h
$(CC) $(CFLAGS) -c $^
description.o: description.c description.h
$(CC) $(CFLAGS) -c $^
debug: $(DOBJ)
$(CC) $^ -o hospital.dbg
hospital.dbg.o: hospital.c
$(CC) $(CFLAGS) -g $# $< -c
parse.dbg.o: parse.c parse.h
$(CC) $(CFLAGS) -g $# $< -c
structure.dbg.o: structure.c structure.h
$(CC) $(CFLAGS) -g $# $< -c
patientList.dbg.o: patientList.c patientList.h
$(CC) $(CFLAGS) -g $# $< -c
diseaseList.dbg.o: diseaseList.c diseaseList.h
$(CC) $(CFLAGS) -g $# $< -c
description.dbg.o: description.c description.h
$(CC) $(CFLAGS) -g $# $< -c
clean:
rm *.o hospital.dbg hospital *~
.PHONY: all clean
Thanks

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

Resources