Makefile troubles - Atmel Xplain display-demo

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

In an new project (based on atmel xplain display-demo) I have a file structure where all source files are stored in several subfolders of the root folder. In the root folder we find the makefile. I have tried to rewrite the makefile which follows the demo source to be less nested. For this I used an earlier version from the avr-gcc makefile example and has rewritten some part of it.

My problem is related to a rule which can not resolve the path to where the source files are thus ending with message

make: *** No rule to make target `$(TARGET).elf', needed by `elf'.  Stop.

Seen that one before? ... thought so.

This beeing the rule failing.

$(OBJDIR)/%.o :  ./%.c
	@echo
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $< -o $@

Its not finding %.c but if giving path to main directly like this

$(OBJDIR)/%.o :  ./apps/display-demo/main.c
	@echo
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $< -o $@

make will start building main. Offcourse failing, but still building.

$(OBJDIR)/%.o is given by
OBJ = $(SRC:./%.c=$(OBJDIR)/%.o) $(CPPSRC:./%.cpp=$(OBJDIR)/%.o) $(ASRC:./%.S=$(OBJDIR)/%.o)

Where SRC is: (sorry for the long listings)

SRC= ./apps/display-demo/main.c ./apps/display-demo/app_desktop.c ./apps/display-demo/app_calibrate.c ./apps/display-demo/app_calc.c ./apps/display-demo/app_clock.c ./apps/display-demo/app_fonts.c ./apps/display-demo/app_files.c 
./apps/display-demo/app_slideshow.c ./apps/display-demo/app_tank.c ./apps/display-demo/app_memgame.c ./apps/display-demo/app_widget.c ./apps/display-demo/file_loader.c ./arch/avr8/arch_hugemem.c ./arch/avr8/delay.c ./board/xplain/board_physmem_pools.c ./board/xplain/init.c 
./chip/atxmega128a1/sysclk.c ./cpu/xmega/physmem_pools.c ./drivers/block/block_core.c ./drivers/block/dataflash.c ./drivers/clk/xmega_pr.c ./drivers/flash/at45_device.c 
./drivers/gfx/gfx_bitmap.c ./drivers/gfx/gfx_generic.c ./drivers/gfx/gfx_text.c ./drivers/gfx/hx8347a/gfx_hx8347a.c ./drivers/gpio/port.c ./drivers/spi/serial/spi_mega_xmega.c 
./drivers/spi/serial/spi_polled.c ./drivers/spi/serial/spi_polled_buf_list.c ./drivers/tc/timer/tc_timer_xmega.c ./drivers/touch/resistive/touch.c ./util/buffer.c ./util/hugemem.c 
./util/malloc_simple.c ./util/membag.c ./util/mempool.c ./util/physmem.c ./util/softirq_common.c ./util/workqueue.c ./util/fs/tsfs.c ./util/gfx/sysfont.c ./util/gfx/win.c ./util/gfx/wtk.c 
./util/gfx/wtk_basic_frame.c ./util/gfx/wtk_button.c ./util/gfx/wtk_check_box.c ./util/gfx/wtk_frame.c ./util/gfx/wtk_label.c 
./util/gfx/wtk_progress_bar.c ./util/gfx/wtk_radio_button.c ./util/gfx/wtk_slider.c ./util/stream/stream_core.c ./util/stream/stream_string.c 
./util/string/generic_memcpy.c ./util/string/generic_memset.c ./util/string/generic_strcmp.c ./util/string/generic_strlen.c

This generate OBJ to be :

OBJ=.obj/apps/display-demo/main.o .obj/apps/display-demo/app_desktop.o .obj/apps/display-demo/app_calibrate.o .obj/apps/display-demo/app_calc.o .obj/apps/display-demo/app_clock.o .obj/apps/display-demo/app_fonts.o .obj/apps/display-demo/app_files.o .obj/apps/display-demo/app_slideshow.o .obj/apps/display-demo/app_tank.o .obj/apps/display-demo/app_memgame.o .obj/apps/display-demo/app_widget.o .obj/apps/display-demo/file_loader.o .obj/arch/avr8/arch_hugemem.o 
.obj/arch/avr8/delay.o .obj/board/xplain/board_physmem_pools.o .obj/board/xplain/init.o .obj/chip/atxmega128a1/sysclk.o .obj/cpu/xmega/physmem_pools.o 
.obj/drivers/block/block_core.o .obj/drivers/block/dataflash.o .obj/drivers/clk/xmega_pr.o 
.obj/drivers/flash/at45_device.o .obj/drivers/gfx/gfx_bitmap.o .obj/drivers/gfx/gfx_generic.o 
.obj/drivers/gfx/gfx_text.o .obj/drivers/gfx/hx8347a/gfx_hx8347a.o .obj/drivers/gpio/port.o .obj/drivers/spi/serial/spi_mega_xmega.o 
.obj/drivers/spi/serial/spi_polled.o .obj/drivers/spi/serial/spi_polled_buf_list.o .obj/drivers/tc/timer/tc_timer_xmega.o .obj/drivers/touch/resistive/touch.o .obj/util/buffer.o 
.obj/util/hugemem.o .obj/util/malloc_simple.o .obj/util/membag.o .obj/util/mempool.o .obj/util/physmem.o .obj/util/softirq_common.o .obj/util/workqueue.o .obj/util/fs/tsfs.o .obj/util/gfx/sysfont.o 
.obj/util/gfx/win.o .obj/util/gfx/wtk.o .obj/util/gfx/wtk_basic_frame.o .obj/util/gfx/wtk_button.o 
.obj/util/gfx/wtk_check_box.o .obj/util/gfx/wtk_frame.o 
.obj/util/gfx/wtk_label.o .obj/util/gfx/wtk_progress_bar.o .obj/util/gfx/wtk_radio_button.o .obj/util/gfx/wtk_slider.o .obj/util/stream/stream_core.o .obj/util/stream/stream_string.o .obj/util/string/generic_memcpy.o .obj/util/string/generic_memset.o 
.obj/util/string/generic_strcmp.o .obj/util/string/generic_strlen.o .obj/arch/avr8/entry.o .obj/arch/avr8/link.lds.o .obj/cpu/xmega/ccp.o

In my brain that should give for main.c that

$(OBJDIR)/%.o :  ./%.c

Should be expanded to

$(OBJDIR)/apps/display-demo/main.o : ./apps/display-demo/main.c

Obviously I am doing something wrong, but need some fresh eyes to see what that could be. Please see attached makefile for more info.

EDIT: I noticed that the dependencies are not generated so I will work to resolve this first. Also the VPATH was not set or used. Will change the script to fix this error.

Attachment(s): 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am stuck...
Clearly I do not understand the life of makefiles.

Since I get the No rule to make target error, the error is most certainly that makefile do not find a rules dependency. Here I am certain that the problem is that the source files are not found.

As seen in my first post, in the makefile. The first rule that is invoked by make all is the elf rule where elf: is depending on @(TARGET).elf

elf: $(TARGET).elf

This is in turn invoking the rule

.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf:  $(OBJ)
	@echo
	@echo $(MSG_LINKING) $@
	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)

As in turn will invoke the rules given by variable OBJ...

As seen in my first post, OBJ is a variable that represents three dependencies for rule %.elf: where $(SRC:./%.c=$(OBJDIR)/%.o) represents the first one, or rather $(OBJDIR)/%.o as seen in rule

$(OBJDIR)/%.o : %.c
	@echo
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $< -o $@

Well, that’s at-least the way I have understand it make will interpret it. Since OBJ is defined with = and not := OBJ will not be expanded before make uses the variable.

Now, This should give that the %, or stem if you prefers, should for first source element in SRC (see first post) be apps/display-demo/main and therefore the rule should become for first element (OBJDIR=.obj)

.obj/apps/display-demo/main.o : apps/display-demo/main.c
	@echo
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $< -o $@

This then fails. I have used the $(warning ...) directive to find where things hangs. I tried to change %.c to ./%.c to ensure that it is referred with relative path from where make is issued.

As before, running code

avr-gcc -c apps/display-demo/main.c -o .obj/apps/display-demo/main.o 

directly will start compilation of main. It seems to me that the value of % is not passed??!!??

As mentioned. I have a structure where a makefile is stored in a project folder, and in subdirectories of this projectfolder you find the source and include files. Each subfolder contains a subdir.mk file which is adding sourcefiles to the SRC variable etc. and including other subdirs if present. The .obj and .dep is wanted to be generated as subdirs directly inside the projectfolder having all deps and objs stored. There are no source files in the project folder.

Reason for doing this is that I want to structure my project differently from earlier where i back then had the makefile and all sources stored in same folder messing things up when projects grows.

Any help will do. I also attach the makefile this time as-well since there are some minor changes. Hope I do not scare you with my rather loooong posts. I just try to describe the problem accurately.

Attachment(s): 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you tried using...

make --debug=basic

and/or?

make --dry-run
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Make is looking for the source files in the same directory as the makefile but you have them in sub directories.

$(OBJDIR)/%.o :  ./%.c
   @echo
   @echo $(MSG_COMPILING) $<
   $(CC) -c $(ALL_CFLAGS) $< -o $@ 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

atomicdog wrote:
Make is looking for the source files in the same directory as the makefile but you have them in sub directories.

I will try your make options as soon I get to my station...

But.. regarding your second post, I thought the % inherited its value from the rule which in turn is formatted by OBJ = $(SRC:./%.c=$(OBJDIR)/%.o) ... . Here the stem gets its value from manipulating what it reads from the SRC string and should end up with apps/display-demo/main therefor it should look for ./apps/display-demo/main.c when interpreting ./%.c

Guess I get an answer when using the make options...

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
$(OBJDIR)/%.o :  ./%.c
   @echo
   @echo $(MSG_COMPILING) $<
   $(CC) -c $(ALL_CFLAGS) $< -o $@ 

For the above rule the percent sign is a wild card for object files in the $(OBJDIR) folder.

.obj/file1.o :  ./file1.c 

The rule doesn't have $(OBJ) it has $(OBJDIR).

I don't think OBJ = $(SRC:./%.c=$(OBJDIR)/%.o) will expand like you expect it to.
You can try making a .phony test rule and adding $(info $(OBJ)) to see how it expands

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

make --debug=basic only reveals what we already know, that $(TRAGET).elf must be built

   File `build' does not exist.
     File `elf' does not exist.
      File `Z_Display_Demo.elf' does not exist.
     Must remake target `Z_Display_Demo.elf'.
make: *** No rule to make target `Z_Display_Demo.elf', needed by `elf'.  Stop.

make --dry-run gives the following with no new information

echo 
echo -------- begin --------
avr-gcc --version
if test -f Z_Display_Demo.elf; then echo; echo Size before:; avr-size --mcu=atxmega128a1 --format=avr Z_Display_Demo.elf; \
	2>/dev/null; echo; fi
make: *** No rule to make target `Z_Display_Demo.elf', needed by `elf'.  Stop.

...

I attached the output from make -p as a file since it is rather big. Pay attention to line 432 and similar. They mention a number of "impossibilities" what is that referring to?

But I think I found where the error occurs. See line 584 and 591 these are the rules invoked and failing.

%.elf: @(OBJ)
is expanded to 
%.elf: .obj/apps/display-demo/main.o ..... 

Thus we get 
$(TARGET).elf: .obj/apps/display-demo/main.o .....

and not  

$(TARGET).elf: $(SRC:./%.c=$(OBJDIR)/%.o) .... 

And therefor there are no stem (%) to pass to the rule 
$(OBJDIR)/%.o: ./%.c
making ./%.c become ./.c

..Or I am totally misunderstanding how things are done.

Attachment(s): 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems like the elf target almost works. The problem is $(OBJ). I removed the ./ from $(OBJ)... it seems to work. $(SRC:%.c=$(OBJDIR)/%.o)
With the dot-slash make doesn't try to build the object files.

I get this (I had to comment out the includes)...

C:\Users\John\Downloads>make --dry-run
echo
echo -------- begin --------
avr-gcc --version
if test -f Z_Display_Demo.elf; then echo; echo Size before:; avr-size --mcu=atxmega128a1 --format=avr Z_Display_Demo.elf; \
        2>/dev/null; echo; fi
echo
echo Linking: Z_Display_Demo.elf
avr-gcc -mmcu=atxmega128a1 -I. -gdwarf-2  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -fno-unit-at-a-time -Wundef -Wunreachable-code -Wsign-compare -
Wa,-adhlns= -I./include -std=gnu99 -Wundef -MMD -MP -MF .dep/Z_Display_Demo.elf.d  --output Z_Display_Demo.elf -Wl,-Map=Z_Display_Demo.map,--cref     -lm
echo
echo Creating load file for Flash: Z_Display_Demo.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock Z_Display_Demo.elf Z_Display_Demo.hex
echo
echo Creating load file for EEPROM: Z_Display_Demo.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
        --change-section-lma .eeprom=0 --no-change-warnings -O ihex Z_Display_Demo.elf Z_Display_Demo.eep || exit 0
echo
echo Creating Extended Listing: Z_Display_Demo.lss
avr-objdump -h -S -z Z_Display_Demo.elf > Z_Display_Demo.lss
echo
echo Creating Symbol Table: Z_Display_Demo.sym
avr-nm -n Z_Display_Demo.elf > Z_Display_Demo.sym
if test -f Z_Display_Demo.elf; then echo; echo Size after:; avr-size --mcu=atxmega128a1 --format=avr Z_Display_Demo.elf; \
        2>/dev/null; echo; fi
echo --------  end  --------
echo
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi and thanks for your effort, but I am afraid it wont help. I tried to strip down the makefile to minimum and tried to use it in an old and very simple project of mine, s simple 7 seg timer.

This was earlier using the default makefile provided by winavr and where all source and headers where stored in project root folder together with the makefile. I now put the files into TWO subdirectories instead and used attached makefile (actually I added the whole project now for anyone interested, guess none). A number of .c and .h files was spread among them.

First it did not compile until I ensured that main.c was first element of SRC (?!?) . This then compiled and linked using a substitute of above rules and OBJ where not changed i.e. still including ./ , so the rules for compiling from subdirs now works as expected.

I then moved one source file (eeprom.c) into its own subdirectory (eeprom) and added it to SRC through ./eeprom/subdir.mk. Then I got an error whining about a missing dependency file. The .dep/eeprom/eeprom.d file. It had the path alright but could not find it.

It turns out that command

$(shell mkdir -p $(OBJDIR)/$(dir $(SRC:./%=%)) 2>/dev/null)
$(shell mkdir -p $(DEPDIR)/$(dir $(SRC:./%=%)) 2>/dev/null)

Is not able to pre-create more than one .obj and one .dep folder, whichever comes first in SRC list, which are ./app/top becoming ./obj/app/top and .dep/app/top . I guess this is because the same folder will be tried to be created many times since SRC have more tan one refference to the same folder thus terminating the command before creating all.

When manually adding ./obj/eeprom AND ./dep/eeprom everything compiles fine again.

So for the moment my task is narrowed down to solve that issue.

EDIT: Well, by not redirecting mkdir command outpuy to the big black hole 2>/dev/null, the problem is thrown right into my face:

mkdir: cannot create directory `.obj/app/top/': No such file or directory
mkdir: cannot create directory `app/top/': File exists
mkdir: cannot create directory `app/top/': File exists
mkdir: cannot create directory `app/': File exists
mkdir: cannot create directory `app/': File exists
mkdir: cannot create directory `app/': File exists
mkdir: cannot create directory `eeprom/': File exists

The way I have written it, only the first element of SRC is actually put in the .obj folder.

Here's the correct variant. Any pitfalls???

$(shell mkdir -p $(dir $(OBJ:%=%)))
$(shell mkdir -p $(dir $(OBJ:$(OBJDIR)%=$(DEPDIR)%)))

However, I might run in to new problems as described in link below whenever I add, delete or move files without running a make clean. I might resolve them to using the examples or just actually do a make clean whenever needed.
http://scottmcpeak.com/autodepen...

Attachment(s): 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm reading this with great interest. My problem is that even the supplied files in the demo software (AVR1913-xplain-software-framework-1.0) do not compile at all. With the uart-example alone I get 54 errors! Most of them related to the gfx module.
What's going on here?
Anyone has had any thoughts on this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have the tmp/ directory in the root of the drive you are building on?
I seem to recall that you get some incomprehensible errors if this is missing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yep, one of the first things I did. Been going through the documentation (mainly AVR1913) with a fine tooth comb, no avail. I did manage to get the demo working, from the supplied binary files, but that's about it. None of the display demos wants to compile at all, not even the (very basic) UART loopback. seems that it can't see any of the included files. I have set search paths, tried to manually assign the files. Nothing. Banging my head against a wall here...
I installed the toolchain on both the Mac and the PC and I get similar if not identical errors on both. Seems the make files are up the spout somehow.
Not many hair left to tear out...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, got it to work and here is how:

for some reason, AVR Studio 4.18 in my previous setup was build 700. After setting up a completely new environment (WinXP within VMware) I installed the original AVR Studio 4.18 which turned out to be Build 684. This one works fine. No other changes were necessary.

Happy compiling!