makefile for ARM: cannot specify -o with -c or -S and mult compilations - gcc

I'm modifying this makefile to use with another project and I get a gcc error saying I cannot specify -o with -c.
The line near the bottom that says:
.c.o:
$(CC) $(CC_FLAGS) ... -o $# &<
has the -o
but CC_FLAGS = $(MCU_CC_FLAGS) -c ...
I don't see how this makefile worked in the first place.

Related

in makefile echoing "compiling" before the compilation

i thought it would be easy but i can't actually figure out nor find on internet, a solution to advertise "compilation of the objects file" (for instance) just before compiling, and avoiding relink in the same time
my makefile would be something like this :
libfrog.a: $(OBJS)
#echo "building the library"
ar -rc $# $^
%.o:%.c
gcc -i. -c -o $# $<
which produce, when prompt "make" :
gcc -I. -c -o file01.o file01.c
gcc -I. -c -o file02.o file02.c
gcc -I. -c -o file03.o file03.c
gcc -I. -c -o file04.o file04.c
gcc -I. -c -o file05.o file05.c
building library
ar -rc libfrog.a file01.o file02.o file03.o file04.o file05.o
but i would like to have :
compilation of the objects files
gcc -I. -c -o file01.o file01.c
gcc -I. -c -o file02.o file02.c
gcc -I. -c -o file03.o file03.c
gcc -I. -c -o file04.o file04.c
gcc -I. -c -o file05.o file05.c
building library
ar -rc libfrog.a file01.o file02.o file03.o file04.o file05.o
now :
1 - if i put an echo before the rule libfrog.a is called (say by creating another first rule), it will print even if i prompt "make" two times and nothing is to be done...
2 - if i put an echo in the rule %.o:%.c it will print for each file
3 - if i put an echo as a dependency of the first rule it will force to relink all the files when prompt "make" again, even when just one file has been modified libfrog.a: echo $(OBJS) (and a rule "echo" which echo the text)...
so I've tried to echo for each compilation but with changing the text to echo nothing, i failed... i tried to create an echo.txt file just to create a rule that would depend on its existence but i failed too. I have no idea if it's possible ?
It's not really simple to do. But if you're using GNU make you can do it with the help of order-only prerequisites:
%.o : %.c | announce
gcc -I. -c -o $# $<
.PHONY: announce
announce:
echo "compilation of the objects files"
Personally I don't think showing this message is needed and I wouldn't add even the above amount of complexity to support it in my makefiles.
But if you really want to do it and you don't want the message to be printed unless some object file needs to be made, you'll have to get really fancy and do something like this:
PRINTED :=
%.o : %.c
$(or $(PRINTED),$(eval PRINTED := :)echo "compilation of the objects files")
gcc -I. -c -o $# $<
Once it's working you'll want to add a # before the first recipe line.

How to compile avr c and c++ source code with make

I was trying to compile some code written in c and c++ for an atmega32u4.
I wrote a makefile from information gathered from the internet, but it fails for some reason.
If I run the commands separately from the command line, they all work. However running the make command gives the following error:
main.cpp:3:10: fatal error: avr/io.h: No such file or directory
The contents of the main.cpp file are not really relevant, it's just a blink code.
The makefile looks like this:
all: init clean $(patsubst %.cpp, %.hex, $(wildcard *.cpp))
avr-size -A $(BUILDPATH)/*.elf
%.c.o: %.c
#mkdir -p $(BUILDPATH)
avr-gcc -c -g -Os -w -mmcu=$(CHIP) $^ -o $(BUILDPATH)/$#
%.cpp.o: %.cpp
#mkdir -p $(BUILDPATH)
avr-g++ -c -g -Os -w -mmcu=$(CHIP) $^ -o $(BUILDPATH)/$#
%.elf: %.o
avr-gcc -g -Os -w -mmcu=$(CHIP) $(BUILDPATH)/$^ -o $(BUILDPATH)/$#
%.hex: %.elf
avr-objcopy -R .eeprom --change-section-lma .eeprom=0 -O ihex $(BUILDPATH)/$^ $(BUILDPATH)/$#
So what am I doing wrong? Do I have to set up some environment variables or is the structure of the makefile incorrect?

Some implicit makefile?

I am trying to understand makefile.
I took atmega168 bootloader's makefile and simplified it to this:
CC = avr-gcc
override CFLAGS = -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
atmega328: ATmegaBOOT_168_atmega328.hex
%.elf: ATmegaBOOT_168.o
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -Wl,--section-start=.text=0x7800 -o $# $<
clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
%.hex: %.elf
avr-objcopy -j .text -j .data -O ihex $< $#
When I ran $ make atmega328 I get:
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -Wl,--section-start=.text=0x7800 -o ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168_atmega328.hex
rm ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168.o
Why cannot I remove CC or CFLAGS?
I understand some basics of makefile. I read a lot on the internet, plus went through gnu manual, but I cannot understand the very first output with ATmegaBOOT_168.c. What/How has generated first command?
Was there used some second makefile? If yes, how to find its location?
UPDATE:
If I rename ATmegaBOOT_168.c to ATmegaBOOT_1681.c. Running $ make atmega328 gives:
make: *** No rule to make target 'ATmegaBOOT_168_atmega328.hex', needed by 'atmega328'. Stop.
but the rule is present.
CC and CFLAGS are variables used in the built in implicit rules of GNU make. When you run make, it reads your makefile a bit like:
No target given, so we'll make the first: atmega328. This requires a .hex file.
The .hex file can be generated from a .elf file per the last rule.
.elf files can be generated by the %.elf rule (which here looks like you've broken the pattern, as there's no % in the dependencies).
There's no rule for .o in this file, so the default recipe $(CC) $(CPPFLAGS) $(CFLAGS) -c is used. Since a .c file is found, this rule is applicable and generates the first command. The rule could have been written (as shown in suffix rules):
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
Backtrack up this list, now that the source has been found, and run the commands.
If the implicit rule variables are left unset, you will typically get programs built for your host system using cc.

Make compiler options

I am running a 32 bit machine with Ubuntu 14.04. I want to execute sudo make to generate a C++ compiled file (gcc-4.8.4). My Makefile is
Makefile (edited based on comments from ddumbugie):
CDefines = -DLINUXGXX
COMPFLAGS =
FlameManCC = gcc
FlameManCCOpts = -O3
OBJECTS = alligator.o
COpts = $(COMPFLAGS) $(FlameManCCOpts) $(CDefines)
CC = $(FlameManCC)
alligator.o: alligator.c
$(CC) $(COpts) -c $< -o $#
Executing
make -n
gives me
gcc -O3 -DLINUXGXX -c alligator.c -o alligator.o
But
sudo make -n
gives me
DLINUXGXX -c alligator.c -o alligator.o
Definitely command DLINUXGXX is not understood. However, I need to remain a super-user for a subsequent command executed by make. How can I resolve this?
CDefines = -DLINUXGXX
COpts = -O3 $(CDefines)
alligator.o: alligator.c
$(CC) $(COpts) -c $< -o $#
It requires -o compiler options.
$# means the target. That is alligator.o.
$< means the dependency. That is alligator.c.

Problems wih make file code

When i run the code below , it give me an error message which is :
cc1: warning: main.c: not a directory [enabled by default]
frequent.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make: * [main] Error 1
CC = gcc
CPPFLAGS = -I
main: main.c headers.h sortt.o frequent.o
#$(CC) $(CPPFLAGS) -c $^ -o $#
sortt.o: headers.h sortt.c
$(CC) $(CPPFLAGS) -c $< -o $#
frequent.o: headers.h frequent_word.c search_similar_word.o
$(CC) $(CPPFLAGS) -c $< -o $#
You have a lot of errors in your rules. Why is frequent.o listing search_similar_word.o as a prerequisite? There's no reason that you can't build frequent.o before or at the same time as search_similar_word.o.
Also, you are using $< in the compilation line which expands to the first prerequisite, but the first prerequisite for frequent.o is headers.h, so you're trying to compile headers.h which is wrong: you want to compile frequent_word.c.
Ditto for sortt.o.
It's also very odd to name your object files with different names than the source files.
In your CPPFLAGS you're listing a -I flag but you've given it no argument: that flag takes a directory as an argument.
And finally, you are using the -c flag when you're trying to link the final object (I'm assuming the comment character # is just an artifact of debugging); that's not right as the -c flag tells the compiler to generate an object file, and to not link the final object.
Your makefile should look something like this:
CC = gcc
CPPFLAGS = -I .
main: main.c headers.h sortt.o frequent.o
$(CC) $(CPPFLAGS) $^ -o $#
sortt.o: sortt.c headers.h
$(CC) $(CPPFLAGS) -c $< -o $#
frequent.o: frequent_word.c headers.h
$(CC) $(CPPFLAGS) -c $< -o $#
I have no idea what to do with search_similar_word.o since it doesn't seem to be used anywhere in your build.

Resources