i have this makefile:
SHELL=/bin/bash
COMPILER_VERSION = "Intel 64 Compiler 16.0.0.109 Build 20150815"
SOURCES = \
ron1.f \
ron2.f \
ron3.f \
ron4.f
OBJECTS = $(SOURCES:.f=.o)
TARGET = mylib.a
FC = gfortran
FFLAGS = -O3
linux: $(TARGET)
#echo
#echo " " \
ar r $(TARGET) $(OBJECTS)
#echo
#echo " " \
ranlib $(TARGET)
#echo
$(TARGET): $(OBJECTS)
$(OBJECTS):$(SOURCES)
cleanall:
#echo
rm -f $(OBJECTS) $(TARGET)
#echo
clean:
#echo
rm -f $(OBJECTS)
#echo
.f.o:
#echo " " \
$(FC) -c $(FFLAGS) $*.f
It results the below output:
prompt> make cleanall
rm -f ron1.o ron2.o ron3.o ron4.o mylib.a
prompt> make
gfortran -c -O3 ron1.f
gfortran -c -O3 ron2.f
gfortran -c -O3 ron3.f
gfortran -c -O3 ron4.f
ar r mylib.a ron1.o ron2.o ron3.o ron4.o
ranlib mylib.a
prompt>
what i am looking to do is create a space between "prompt> make" and the first happening of gfortran.
and ideally i would like the output on the screen to first print out the contents of my COMPILER_VERSION variable before the first gfortran happens, such that the output would look like
prompt> make
makefile written for: Intel 64 Compiler 16.0.0.109 Build 20150815
gfortran -c -O3 ron1.f
gfortran -c -O3 ron2.f
gfortran -c -O3 ron3.f
and so on...
any help much appreciated.
You should add to the 'linux' target some prerequisite like 'ECHO' here:
linux: ECHO $(TARGET)
ar r $(TARGET) $(OBJECTS)
#echo
#echo " " \
ranlib $(TARGET)
#echo
ECHO:
#echo "\n\n\n\n Makefile written for the compiler version ${COMPILER_VERSION}"
thanks a bunch, that worked.
your
linux: ECHO $(TARGET)
worked great, only thing i did different than what you typed was this syntax for ECHO: which i placed at the bottom of the makefile. It allowed me to space out the screen output exactly how i wanted it.
ECHO:
#echo
#echo "Makefile written for compiler version ${COMPILER_VERSION}"
#echo
You can use echo with flag -e
#echo -e "\n"
Related
I'm compiling a 8051 project with SDCC but has a problem with Makefile, the following sources:
TARGET = test
CC = sdcc
CFLAGS = -Wall -I.
RM = rm -rf
SRCS = $(wildcard *.c)
RELS = $(patsubst %.c,%.rel,$(SRCS))
$(TARGET).bin: $(TARGET).hex
objcopy -I ihex -O binary $< $#
$(TARGET).hex: $(TARGET).ihx
packihx $< > $#
$(TARGET).ihx: $(RELS)
#echo Linking ...
$(CC) $(CFLAGS) $< -o $#
#echo Build finish!
%.rel: %.c
#echo Compiling ...
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
#echo Removing ...
$(RM) *.rel *.ihx *.lk *.lst *.map *.mem *.rst *.sym *.asm $(TARGET)
#echo Removed!
When I run make it has errors:
minh#PCDESIGN:~/workspaces/programMSC51/test$ make
Compiling ...
sdcc -Wall -I. -c main.c -o main.rel
sdas Assembler V02.00 + NoICE + SDCC mods (Intel 8051)
Copyright (C) 2012 Alan R. Baldwin
This program comes with ABSOLUTELY NO WARRANTY.
Usage: [-Options] file
Usage: [-Options] outfile file1 [file2 file3 ...]
-d Decimal listing
-q Octal listing
-x Hex listing (default)
-g Undefined symbols made global
-a All user symbols made global
-b Display .define substitutions in listing
-bb and display without .define substitutions
-c Disable instruction cycle count in listing
-j Enable NoICE Debug Symbols
-y Enable SDCC Debug Symbols
-l Create list file/outfile[.lst]
-o Create object file/outfile[.rel]
-s Create symbol file/outfile[.sym]
-p Disable automatic listing pagination
-u Disable .list/.nlist processing
-w Wide listing format for symbol table
-z Disable case sensitivity for symbols
-f Flag relocatable references by ` in listing file
-ff Flag relocatable references by mode in listing file
-I Add the named directory to the include file
search path. This option may be used more than once.
Directories are searched in the order given.
removing
make: *** [Makefile:22: main.rel] Error 1
How can I fix this?
Unlike other compilers, SDCC does not have a -Wall option. You should remove it from CFLAGS = -Wall -I. in the Makefile.
It also does not have a replacement. There are options --less-pedantic and -Werror, which gives you fewer warnings, or treats warnings as errors, respectively, but there is no option for creating more warnings.
The manual mentions --more-pedantic, but
Actually this is not a SDCC compiler option but if you want more warnings you can use a separate tool dedicated to syntax checking [...]
See SDCC Compiler User Guide (version 4.1.12), section 3.3.4.
I have inherited a project file that has a Makefile in it that is doing something I have never seen before--It is injecting a rm command. I cannot find any reason for the rm command, so I am missing something very obvious or very esoteric.
Thanks
The results of running make are:
bison --defines --xml --graph=calc.gv -o calc.c calc.y
Bison flags =
cc -c -o calc.o calc.c
Making BASE = calc
cc -o calc calc.o
Done making BASE
rm calc.c <======== WHERE IS THIS COMING FROM?
The Makefile is:
BASE = calc
BISON = bison
XSLTPROC = xsltproc
all: $(BASE)
%.c %.h %.xml %.gv: %.y
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
#echo "Bison flags = " $(BISONFLAGS)
$(BASE): $(BASE).o
#echo "Making BASE = " $(BASE)
$(CC) $(CFLAGS) -o $# $^
#echo "Done making BASE"
run: $(BASE)
#echo "Type arithmetic expressions. Quit with ctrl-d."
./$<
html: $(BASE).html
%.html: %.xml
$(XSLTPROC) $(XSLTPROCFLAGS) -o $# $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
CLEANFILES = $(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
clean:
#echo "Running clean" $(CLEANFILES)
rm -f $(CLEANFILES)
See https://www.gnu.org/software/make/manual/make.html#Chained-Rules:
The second difference is that if make does create b in order to update something else, it deletes b later on after it is no longer needed. Therefore, an intermediate file which did not exist before make also does not exist after make. make reports the deletion to you by printing a rm -f command showing which file it is deleting.
I have an error while making my makefile in linux. Here's my code:
CC = gcc
CFLAGS = -Wall -m32 -g -fno-stack-protector -z execstack -O0
SHELL_SOURCES = Shell.c
SHELL = Shell
.PHONY: all target1 clean
all: target1
target1: $(SHELL)
$(SHELL): $(SHELL_SOURCES)
$(CC) $(CFLAGS) $^ -o $#
clean:
rm -rf $(SHELL)
The error I get is:
gcc -Wall -m32 -g -fno-stack-protector -z execstack -O0 Shell.c -o Shell
make: Shell: Command not found
Makefile:16: recipe for target 'Shell' failed
make: *** [Shell] Error 127
You can't use SHELL as a variable in a Makefile, it is used to know what shell (/bin/sh, /bin/bash, etc) will be used in your Makefile.
CC = gcc
CFLAGS = -Wall -m32 -g -fno-stack-protector -z execstack -O0
EXE_SOURCES = Shell.c
EXE = Shell
.PHONY: all target1 clean
all: target1
target1: $(EXE)
$(EXE): $(EXE_SOURCES)
$(CC) $(CFLAGS) $^ -o $#
clean:
rm -rf $(EXE)
Take more time to read documentation of GNU make
You should remove spaces around variable assignments, e.g. code
CC= gcc
Beware that tab characters are significant in Makefile-s (in rules, for their action lines). Use some editor aware of that (e.g. emacs has a mode for Makefile). See also this example (but the rule action should really start with a tab character). Notably, you need a tab just before the $(CC) $(CFLAGS) $^ -o $# and another one before rm.
Consider also using remake -x to debug your Makefile, or at least make --trace
But the main bug was indeed, as answered by Cpatricio, to use the SHELL variable. Be careful when using variables or names already known to make. Actually, I have the habit of prefixing my make variable names with a common prefix, so you could have defined your variables like JOJOIGA_SOURCES=$(wildcard *.c), JOJOIGA_SHELL=Shell etc....
I am trying to analyze the following makefile and reproduce its "behavior" step by step.
Although I type "make all" it seems this makefile skips the "all:" line and jumps straight to "build/*.o" (hence the echo's).
The file and its corresponding output:
TOOLCHAIN ?= arm-none-eabi-
SOURCES = Demo/main.c \
Demo/startup.c \
Demo/Drivers/rpi_gpio.c \
Demo/Drivers/rpi_irq.c \
Source/tasks.c \
Source/list.c \
Source/portable/GCC/RaspberryPi/port.c \
Source/portable/GCC/RaspberryPi/portisr.c \
Source/portable/MemMang/heap_4.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
INCDIRS = Source/include Source/portable/GCC/RaspberryPi \
Demo/Drivers Demo/
CFLAGS = -Wall $(addprefix -I ,$(INCDIRS))
CFLAGS += -D RPI2
CFLAGS += -march=armv7-a -mtune=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
ASFLAGS += -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
LDFLAGS =
.PHONY: all clean
all: $(MOD_NAME)
echo "in all"
$(MOD_NAME): $(OBJECTS)
echo "in mod name"
ld -shared $(LDFLAGS) $< -o $#
build/%.o: %.c
echo -e "\nin build/*.o:*.c\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $#
build/%.o: %.s
echo -e "in build/*.o:*.s\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)as $(ASFLAGS) $< -o $#
all: kernel7.list kernel7.img kernel7.syms kernel7.hex
echo -e"in kernel all\n"
$(TOOLCHAIN)size kernel7.elf
kernel7.img: kernel7.elf
$(TOOLCHAIN)objcopy kernel7.elf -O binary $#
echo -e "in kernel7.img\n"
kernel7.list: kernel7.elf
echo -e "kernel7.list\n"
$(TOOLCHAIN)objdump -D -S kernel7.elf > $#
kernel7.syms: kernel7.elf
echo -e "kernel7.syms\n"
$(TOOLCHAIN)objdump -t kernel7.elf > $#
kernel7.hex : kernel7.elf
echo -e "kernel7.hex\n"
$(TOOLCHAIN)objcopy kernel7.elf -O ihex $#
kernel7.elf: $(OBJECTS)
echo -e "kernel7.elf\n"
$(TOOLCHAIN)ld $^ -static -Map kernel7.map -o $# -T Demo/raspberrypi.ld
clean:
rm -f $(OBJECTS)
rm -f kernel7.list kernel7.img kernel7.syms
rm -f kernel7.elf kernel7.hex kernel7.map
rm -rf build
echo -e "cleaning \n"
I tried to replicate this behaviour myself with a tiny piece of code. But it doesn't seem to work:
SOURCES = Demo/Drivers/rpi_irq.c \
Demo/Drivers/rpi_gpio.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
.PHONY: all clean
all: $(MOD_NAME)
echo "making all"$(SOURCES)
$(MOD_NAME): $(OBJECTS)
echo "MOD_NAME"
build/%.o:%.c
mkdir -p $(dir $#)
arm-none-eabi-gcc -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=har $< -o $#
As you can see thanks to the echo's my code just doesn't even build my source code. I'd expect it to go from all->MOD_NAME->build. (This is all the output I get)
So my questions are:
How does the makefile I am analyzing manage to go straight to build/*.o?
Why does my implementation, which I think should do the same doesn't even compile my source code?
The Makefile that you copied contains 2 rules for "all".
The first depends on $(MOD_NAME) which might be empty.
The second rule depends on multiple files "kernel7.*" which themselves depend on "kernel7.elf".
Finally "kernel7.elf" depends on $(OBJECTS).
This last rule is responsible that all your source files will be compiled.
The first rule with $(MOD_NAME) does not need to cause any compilation at all.
In your own Makefile you only have a rule for "all" depending on $(MOD_NAME).
If $(MOD_NAME) is empty in your Makefile as well, you do not have any dependency for "all" at all.
If "all" does not depend on anything, no source files will be compiled.
To solve your problem you need to provide some content for $(MOD_NAME).
all is trying to build $(MOD_NAME), which has dependencies of $(OBJECTS), which it is trying to build.
There are two all's here, which is a problem.
I am getting an error when running the following makefile with make -f makefile2 install (apart install the rest is working):
all:myapp
#which compiler
CC = gcc
#Where to install
INSTDIR = /usr/local/bin
#where are include files kept
INCLUDE = .
#Options for development
CFLAGS = -g -Wall -ansi
#Options for release
# CFLAGS = -O -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else
echo "Sorry, $(INSTDIR) does not exist";\
fi
I'm getting the following error:
error /bin/sh: 7: Syntax error: end of file unexpected
make: *** [install] Error 2
From what I understand it is a white space/tabulation/non unix character problem in the last lines of the makefile (after install:). But even trying to delete all spaces and replacing with tabulation I didn't manage to run the makefile properly. The code comes directly from a programming book I'm reading and is an example. Any help appreciated!
You're missing a trailing slash on your else under the install rule. It should be:
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else\
echo "Sorry, $(INSTDIR) does not exist";\
fi