Output some newlines through Makefile - gcc

Below is my makefile:
TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -pthread -Wextra -Wall -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code
.PHONY: clean all default
default: $(TARGET) clean
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $#
clean:
-rm -f *.o
With the flags above and a few files in the directory, the output makes it extremely difficult to find warnings:
How can I get newlines in between each call to GCC? Maybe get the warnings to stand out a bit more?

You can silence the command itself and replace it with something shorter.
CPPFLAGS := -MMD -MP
CFLAGS := -pthread -Wextra -Wall -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code
LDLIBS := -lm
objects := $(patsubst %.c, %.o, $(wildcard *.c))
deps := $(objects:.o=.d)
.PHONY: all clean
prog: $(objects)
$(LINK.o) $^ $(LDLIBS) -o $#
%.o: %.c
#echo Compiling $<
#$(COMPILE.c) -o $# $<
clean: ; $(RM) $(objects) $(deps)
-include $(deps)
A few other things:
Prefer := to =
LDLIBS is the standard variable for libraries as used in make's built-in recipes
make defaults CC to cc, which should be a link to your default compiler, you don't usually need to set CC
Your default target will break parallel builds (-j), I wouldn't bother with it
This makefile doesn't need an all rule, just make the target the first rule
Watch out with wildcard and sources, it's usually safer to specify them manually
You're making each object file depend on every header, just use built-in depedency generation instead (-MMD -MP, include)
make already has recipes for object linking and compiling, reuse them
make defaults $(RM) to rm -f

Related

How can I automatically add '.s' to a target in my Makefile?

I have a phony debug and asm target. debug works by updating the variable CFLAGS and then compiles the normal target, which uses these new CFLAGS to produce debug symbols. This works as intended.
Analogously I want to define the asm target set the -S switch and to change the output name from file to file.s. However, the last part does not work, and I get:
$ make asm -B
gcc -fmessage-length=0 -ansi -pedantic -Werror -Wall -Wextra -Wwrite-strings -Winit-self -Wcast-align -Wcast-qual -Wpointer-arith -Wstrict-aliasing -Wformat=2 -Wmissing-declarations -Wmissing-include-dirs -Wno-unused-parameter -Wuninitialized -Wold-style-definition -Wstrict-prototypes -Wmissing-prototypes -Wdouble-promotion -S -masm=intel file.c -o file
notice the last part [..] -S -masm=intel file.c -o file with the extra parameters but without the .s extension.
What am I missing?
Makefile:
TARGET=file
SOURCE=*.c
HEADERS=*.h
TESTS=*.sh
PROJECT=$(TARGET) $(SOURCE) $(HEADERS) $(TESTS) Makefile
CC=gcc
CFLAGS=\
-ansi \
-pedantic \
-Wall \
# makefile-rules that don't produce files directly
.PHONY: default all debug asm
default: $(TARGET)
# Compile
$(TARGET): $(SOURCE) $(HEADERS) $(TESTS)
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += -DDEBUG -ggdb
debug: $(TARGET)
asm: CFLAGS +=-S -masm=intel
asm: TARGET +=.s <------------------ THIS LINE !!!!!!
asm: $(TARGET)
You could just add a $(TARGET).s target to the rule and use that in asm:
$(TARGET) $(TARGET).s: $(SOURCE) $(HEADERS) $(TESTS)
$(CC) $(CFLAGS) $< -o $#
asm: CFLAGS += -S -masm=intel
asm: $(TARGET).s

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)

CPPUTestMakeFile Help linking

I am trying to make a makefile, which can make an exe for CppUTest. It can not find the headers, what have I done wrong? First time making a makefile, not 100% sure what I'm doing.
#The compiler to use
CC = g++
LINK = -g -pedantic -Wall -lstdc++ -lpthread -ldl -lm -Wl,-rpath,.
COMPILE = -g -O3 -D_THREAD_SAFE -pedantic -Wall -c -Wno-deprecated
#Name of the EXE file to create.
EXE = ./Tests
SRCS = $(shell ls *.cpp)
OBJS = $(subst .cpp,.o,$(SRCS))
#Extra flags to give to the C compiler.
CFLAGS =
#Libraries to include
LIBS= -lCppUTestExt -lCppUTest -lm
#Extra flags to give to the C++ compiler.
CXXFLAGS = -I/home/mg/DS-5-Workspace/Tests/include
#Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’,
#such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
#instead.
LDFLAGS = -L/home/mg/DS-5-Workspace/Tests/cpputest/lib
#Extra flags to give to the C preprocessor and programs that use it (the C and
#Fortran compilers).
CPPFLAGS =
.SUFFIXES: .o .cpp
.cpp.o:
$(CC) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(COMPILE) $(LIBS) $<
all: $(OBJS)
$(CC) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LIBS) $(OBJS) -o $(EXE) $(LINK)
-include depend.mak
depend:
g++ -MM $(SRCS) > depend.mak
#static:
#ar -crvs $(a) $(OBJS)
#shared: $(OBJS)
#$(CC) -shared -Wl,-soname -lc -o $(so) $(OBJS)
clean:
rm -rf $(OBJS) depend.mak $(EXE) $(so) $(a)
I have the following error:
error: CppUTest/CommandLineTestRunner.h: No such file or directory
Well, you're mixing up a lot of things.
Let's clean this up and keep only what is needed :
EXE := Tests
SRC_DIR := .
OBJ_DIR := obj
SRC := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
CPPFLAGS := -I/home/mg/DS-5-Workspace/Tests/include
CPPFLAGS += -MMD -MP -D_THREAD_SAFE
CXXFLAGS := -W -Wall -Wno-deprecated -pedantic -O3 -g
LDFLAGS := -L/home/mg/DS-5-Workspace/Tests/cpputest/lib
LDFLAGS += -Wl,-rpath,.
LDLIBS := -lCppUTestExt -lCppUTest -lm -lstdc++ -lpthread -ldl
.PHONY: all clean fclean re
all: $(EXE)
clean:
$(RM) -f -r $(OBJ_DIR)
fclean: clean
$(RM) -f $(EXE)
re: fclean all
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
# %.a: $(OBJ)
# $(AR) crvs $# $^
# ranlib $#
# %.so: CXXFLAGS += -fPIC
# %.so: $(OBJ)
# $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR):
#mkdir -p $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
-include $(OBJ:.o=.d)
Some explanations :
Avoid the $(shell ...) function, because it'll be executed each time the variable is called if assigned with the = operator instead of := operator.
$(CC) is a built-in variable containing cc or gcc (should be equivalent). Use the built-in $(CXX) to use g++.
-g, -pedantic, -O3, -Wno-deprecated and -Wall are compiler flags, they should be in the CFLAGS (for C) or CXXFLAGS (for C++) built-in variables.
-I <path> and -D_THREAD_SAFE are preprocessor flag, thus should be in the CPPFLAGS built-in variable.
-MMD -MP will auto-generate dependency files (.d extension) for each .o file. You can read more here.
.cpp.o: is a suffix rule, and suffix rules are the old-fashioned way of defining implicit rules for make. You should just rely upon these implicit rules make already know about or make your own the modern way.
You don't need to define .SUFFIXES: by yourself for such widely used targets. The variable SUFFIXES is defined to the default list of suffixes before make reads any makefiles. Make 3.82 defines these suffixes by default :
.SUFFIXES: .out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el
If you have any questions, go on.

Creating a simple Makefile to build a shared library

I am trying to create a very basic hand crafted Makefile to create a shared library to illustrate a point.
This is what I have so far:
SHELL = /bin/sh
CC = gcc
FLAGS = -std=gnu99 -Iinclude
CFLAGS = -fPIC -pedantic -Wall -Wextra -march=native -ggdb3
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
TARGET = example.so
SOURCES = $(shell echo src/*.c)
HEADERS = $(shell echo include/*.h)
OBJECTS = $(SOURCES:.c=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)
When I run make, it attempts to build an application - and ld fails because it can't resolve main().
Problem seems to be with CFLAGS - I have specified -fPIC but that is not working - what am I doing wrong?
Edit
I added the -shared flag as suggested, when I run make, I got this error:
gcc -std=gnu99 -Iinclude -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3 -O0 -D _DEBUG -o example.so src/example.o
/usr/bin/ld: src/example.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/example.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [example.so] Error 1
Which seems to be suggesting to revert back to -fPIC only.
BTW, my new CFLAGS setting is:
CFLAGS = -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3
I am running gcc v4.4.3 on Ubuntu 10.0.4.
The solution was to modify the XXFLAGS as follows:
FLAGS = # -std=gnu99 -Iinclude
CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS = -shared
Compile with -shared:
gcc -o libfoo.so module1.o module2.o -shared
(This also works on MingW under Windows to produce DLLs.)
Example for C++ files. I've also included a clean target.
.PHONY : clean
CPPFLAGS= -fPIC -g
LDFLAGS= -shared
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS=$(SOURCES:.cpp=.o)
FIKSENGINE_LIBDIR=../../../../lib
FIKSENGINE_INCDIR=../../../../include
TARGET=$(FIKSENGINE_LIBDIR)/tinyxml.so
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CPPFLAGS) $(OBJECTS) -o $# $(LDFLAGS)
Since you try to build so file, you probably need -shared.
this is my goto makefile rule for so files:
%.so: %.o ; $(LINK.c) $(LDFLAGS) -shared $^ -o $#
can be used like so
CFLAGS+=-fPIC
libmyfoo.so: # create from libmyfoo.o
# or
libmyfoo.so: myfoo.o # create from myfoo.o

Compiling error

I downloaded someone's source code for a program and i needed to make some changes.
Now i want to compile it but it doesn't seem to work.
PROGS = isotociso
COMMON = tools.o bn.o ec.o wiidisc.o rijndael.o
DEFINES = -DLARGE_FILES -D_FILE_OFFSET_BITS=64
LIBS = C:/Dev-Cpp/lib/libwsock32.a C:/Dev-Cpp/lib/libcrypto.a C:/Dev-Cpp/lib/libcomdlg32.a
CC = gcc
#CFLAGS = -Wall -W -Os -Ilibwbfs -I.
CFLAGS = -Wall -m32 -W -ggdb -Ilibwbfs -I.
LDFLAGS = -m32 -static
VPATH+=libwbfs
OBJS = $(patsubst %,%.o,$(PROGS)) $(COMMON)
all: $(PROGS)
$(PROGS): %: %.o $(COMMON) Makefile
$(CC) $(CFLAGS) $(LDFLAGS) $< $(COMMON) $(LIBS) -o $#
$(OBJS): %.o: %.c tools.h Makefile
$(CC) $(CFLAGS) $(DEFINES) -c $< -o $#
clean:
-rm -f $(OBJS) $(PROGS)
Output
C:\Users\Panda\Desktop\uloader_v4.1\src\isotociso\src>make
gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -c i
sotociso.c -o isotociso.o
process_begin: CreateProcess((null), gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLAR
GE_FILES -D_FILE_OFFSET_BITS=64 -c isotociso.c -o isotociso.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [isotociso.o] Error 2
What would be the problem?
Looks to me as if gcc is not in your PATH.
It also looks like you need MinGW to get the libraries.
I am no expert in C(++) development under Windows, but my interpretation would be that it can't find the compiler itself. What development environment are you using?
It looks like it can't find a file. Are you sure you have all the required source files?

Resources