How can I automatically add '.s' to a target in my Makefile? - 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

Related

Why does ```CFLAGS:=$(CFLAGS) -O3``` not work as expected?

Makefile like this:
CFLAGS := $(CFLAGS) -O3
test: main.o
gcc $(CFLAGS) -o $# $^
clean:
rm test *.o -f
compile 1: command: make, output: gcc -O3 -o test main.c
compile 2: command: make CFLAGS="-Wall -Werror", output: gcc -Wall -Werror -o test main.c
question: why not output: gcc -Wall -Werror -O3 -o test main.c ?
use override directive:
override CFLAGS := $(CFLAGS) -O3
or
override CFLAGS += -O3

Output some newlines through Makefile

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

make is ignoring some depedencies

Here is my Makefile:
CC=gcc
CFLAGS=-Wall -std=gnu99
OBJ1=mknlrescs.o collisionsys.o csheader.o utils.o labels.o csdata.o
OBJ2=mknrescs.o utils.o
all: mknlrescs mknrescs
mknlrescs: $(OBJ1)
$(CC) $(CFLAGS) -o $# $<
mknrescs: $(OBJ2)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
When I type make mknlrescs I get the following:
$ make mknlrescs
gcc -Wall -std=gnu99 -c -o mknlrescs.o mknlrescs.c
gcc -Wall -std=gnu99 -c collisionsys.c
gcc -Wall -std=gnu99 -c csheader.c
gcc -Wall -std=gnu99 -c utils.c
gcc -Wall -std=gnu99 -c labels.c
gcc -Wall -std=gnu99 -c csdata.c
gcc -Wall -std=gnu99 -o mknlrescs mknlrescs.o -lm
mknlrescs.o: In function `main':
mknlrescs.c:(.text+0x4b): undefined reference to...
And a bunch of other "undefined reference to..." errors.
The rest of the objects are not being linked. Notice it only linked the first object file. How can I correct this?
The automatic variable $< stands for the first prerequisite of the rule that defined the recipe.
If you want to use ALL the prerequisites, use $^ instead.
See Automatic Variables for a full list.

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