1

I have the following setup. Two folders named /driverlib and /inc on the main folder and on the same folder I have a linker file and two c files, startup_gcc and blink.c.

I followed a template I found online for STM32F4. I modified it and tried to include both directories on my folder. However I am getting the following error:

C:\Users\D\Documents\ARM-Tiva\blinky3>make
driverlib/adc.c:49:24: fatal error: inc/hw_adc.h: No such file or directory
compilation terminated.
make: *** [driverlib/adc.o] Error 1

Can somebody explain to me how to include both directories so that the /inc folder is visible to the /driverlib folder.

Here's the makefile:

OBJCOPY     = $(TC)-objcopy
OBJDUMP     = $(TC)-objdump
SIZE        = $(TC)-size

###################################################
# Set Include Paths
INCLUDES    = -I /inc 
INCLUDES    = -I /driverlib

# Set Sources
LIB_SRCS    = $(wildcard driverlib/*.c)
USER_SRCS   = $(wildcard src/*.c)

# Set Objects
LIB_OBJS    = $(LIB_SRCS:.c=.o)
USER_OBJS   = $(USER_SRCS:.c=.o) startup_gcc.o


# Set Libraries
LIBS        = -lm -lc

###################################################
# Set Board
MCU         = -mthumb -mcpu=cortex-m4
DEFINES     = -DPART_LM4F120H5QR -DTARGET_IS_BLIZZARD_RA1

# Set Compilation and Linking Flags
CFLAGS      = $(MCU) $(FPU) $(DEFINES) $(INCLUDES) \
            -g -Wall -std=gnu90 -O0 -ffunction-sections -fdata-sections
ASFLAGS     = $(MCU) $(FPU) -g -Wa,--warn -x assembler-with-cpp
LDFLAGS     = $(MCU) $(FPU) -g -gdwarf-2 \
            -Ttivalinker.ld \
            -Xlinker --gc-sections -Wl,-Map=$(PROJ_NAME).map \
            $(LIBS) \
            -o $(PROJ_NAME).elf

###################################################
# Default Target
all: $(PROJ_NAME).bin info

# elf Target
$(PROJ_NAME).elf: $(LIB_OBJS) $(USER_OBJS)
    @$(CC) $(LIB_OBJS) $(USER_OBJS) $(LDFLAGS)
    @echo $@

# bin Target
$(PROJ_NAME).bin: $(PROJ_NAME).elf
    @$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
    @echo $@

#$(PROJ_NAME).hex: $(PROJ_NAME).elf
#   @$(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex
#   @echo $@

#$(PROJ_NAME).lst: $(PROJ_NAME).elf
#   @$(OBJDUMP) -h -S $(PROJ_NAME).elf > $(PROJ_NAME).lst
#   @echo $@

# Display Memory Usage Info
info: $(PROJ_NAME).elf
    @$(SIZE) --format=berkeley $(PROJ_NAME).elf

# Rule for .c files
.c.o:
    @$(CC) $(CFLAGS) -c -o $@ $<
    @echo $@

# Rule for .s files
.s.o:
    @$(CC) $(ASFLAGS) -c -o $@ $<
    @echo $@

# Clean Target
clean:
    $(RM) $(LIB_OBJS)
    $(RM) $(USER_OBJS)
    $(RM) $(PROJ_NAME).elf
    $(RM) $(PROJ_NAME).bin
    $(RM) $(PROJ_NAME).map

The issue is obviously at this paragraph:

###################################################
# Set Include Paths
INCLUDES    = -I /inc 
INCLUDES    = -I /driverlib

# Set Sources
LIB_SRCS    = $(wildcard driverlib/*.c)
USER_SRCS   = $(wildcard src/*.c)

# Set Objects
LIB_OBJS    = $(LIB_SRCS:.c=.o)
USER_OBJS   = $(USER_SRCS:.c=.o) startup_gcc.o

I cannot understand why driverlib does not include the inc directory files.

EDIT

I wanted to clarify my setup for future reference: On the main folder called blinky I have three folders : driverlib, inc and src. The driverlib and inc folders are taken from the TivaWARE folder while the src folder contains the blinky.c and startup_gcc.c file. Given the following if you use make you obtain the following :

C:\Users\D\Documents\ARM-Tiva\blinky>make
driverlib/adc.c:49:24: fatal error: inc/hw_adc.h: No such file or directory
compilation terminated.
make: *** [driverlib/adc.o] Error 1   

This shows that the file adc.c in the driverlib folder cannot include the file hw_adc.h in

I modified the Makefile following the suggestions below:

# Set Sources
LIB_SRCS    = $(wildcard driverlib/*.c)
USER_SRCS   = $(wildcard src/*.c)

# Set Objects
LIB_OBJS    = $(LIB_SRCS:.c=.o)
USER_OBJS   = $(USER_SRCS:.c=.o) src/startup_gcc.o

# Set Include Paths
INCLUDES    = -Idriverlib/ \
            -Iinc \
            -Isrc/

Betas solution was helpful , the only issue was that I did not want to edit all the files in the driverlib folder. The naming convention of the directories was not my decision. If you can see all the files in the driverlib folder you'll find out that each driver file , CAN driver for example or ADC) follows this convention :

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h" 

So right now I understand where the issue is but I lack the understanding to edit the Makefile. Normally if files can.c and can.h are in folder driverlib using #include "can.h" would suffice so I do not understand what's the point of using #include "driverlib/can.h" if all .h and .c files are in the same driverlib folder . If I edit all the inc/ header then I can get a working binary file. The aim however was not to modify the default stock driver files and folders obtained from TI but to use the Makefile.

So to clarify if you follow Betas solution and edit all the files , or if you put all the files in one big directory then you can get a working binary file. Also for future reference I found I could use Energia for what I am doing since it uses the same compiler and TIVA includes the complete peripheral library burned on ROM.

Dimo
  • 51
  • 1
  • 6
  • Maybe a duplicated question: http://stackoverflow.com/questions/4134764/how-to-define-several-include-path-in-makefile – WKPlus Dec 25 '13 at 03:13
  • I already tried that. I still get the same error. I also tried reading the Make manual without too much success. – Dimo Dec 25 '13 at 04:16
  • "inc/hw_adc.h" is not in "/inc" or "/driverlib". Maybe you can replace "inc/hw_adc.h" with "hw_adc.h" if you already add the "inc/" in the include path. – WKPlus Dec 25 '13 at 04:30
  • I did that and it works it that way if I remove the directory part from the headers of the main file. What i did is that I put all the files in one big directory and found that they compile perfectly I can get a bin file. Everything stops working when they are put back into directories. Here are the headers of the main file : #include #include #include "inc/tm4c123gh6pm.h" #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/gpio.h" #include "driverlib/systick.h" – Dimo Dec 25 '13 at 15:22
  • It's generally a bad idea to spell out paths in the `#include` directives. Could you show us the `#include` directives in `adc.c`? – Beta Dec 25 '13 at 15:30
  • Here: #include #include #include "inc/hw_adc.h" #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_sysctl.h" #include "driverlib/adc.h" #include "driverlib/debug.h" #include "driverlib/interrupt.h" – Dimo Dec 25 '13 at 15:41

2 Answers2

1

I don't know the cause of the error exactly, but this is not correct:

INCLUDES    = -I /inc 

# Now INCLUDES is "-I /inc"

INCLUDES    = -I /driverlib

# Now INCLUDES is "-I /driverlib", and inc has been forgotten.

I think you mean this:

INCLUDES    = -I /inc 
INCLUDES    += -I /driverlib

EDIT:

It's generally a bad idea to spell out paths in the #include directives. In adc.c, change this:

#include "inc/hw_adc.h"

to this:

#include "hw_adc.h"

and in the makefile remove the leading slashes (since you won't always be in the root directory):

INCLUDES    = -I inc 
INCLUDES    += -I driverlib
Beta
  • 96,650
  • 16
  • 149
  • 150
  • I tried that with the same result. After the suggestion from WKPlus I tried including it this way INCLUDES = -I /inc -I /driverlib and I still get the same result again. – Dimo Dec 25 '13 at 15:44
  • Ok , as I mentioned before if I put all the files in one big directory it works since I get a working bin file. I wanted to organize the mess by keeping the default structure – Dimo Dec 26 '13 at 01:53
  • @Dimo: Keeping what "default structure"? Which part of my solution do you dislike? – Beta Dec 26 '13 at 05:54
  • The default structure contain only two directories and the unmodified source files. I did not want to modify all the files in the driver lib to remove the inc part from the header file since each specific driver includes this #include "inc/hw_something.h". The first part of the solution that you proposed does not work, that is I still get the same error message. I think the way to do this is to use Makefiles in each directory. Also I cannot up-vote you somehow. – Dimo Dec 26 '13 at 18:20
  • @Dimo: Maybe we have a language problem, but it is not clear what you want, and you seem to be attempting solutions without understanding them. All I can do is wish you luck. – Beta Dec 26 '13 at 18:46
  • Thanks for the help. All I meant is that I would not like to change the header files that were provided by Texas Instruments; that's what I mean by default structure. – Dimo Dec 26 '13 at 22:40
1

The most helpful thing would have been if you had provided the actual complete path of one of the header files which is not being found, in your question, and an example compile line run by make in addition to the error message. Given that information it's trivial to see what's wrong.

It looks like some miscommunication is happening. You write two folders named /driverlib and /inc on the main folder. A folder name that begins with a / is by definition at the root of the directory structure, not within any other folder. I don't know what you mean by on the main folder.

The first thing I'll say is that you're using Windows (as can be seen by your command line prompt), and so you need to be sure that the version of make you're using will do the right thing converting Windows pathnames to UNIX pathnames. For example if you're using Cygwin version of GNU make, then I think the paths you're using are not correct.

Second, I note that you are using -I /inc; that is, the inc directory is at the root of your filesystem. Is that what you intended? Beta's answers have changed that to -I inc, which means the directory inc as a subdirectory of the current working directory, which could be quite different.

Third, if the pathname to the headers is /inc/hw_adc.h and you have -I /inc on your command line and #include "inc/hw_adc.h", I'm sure you can see how this will absolutely not work. The compiler will be looking for header files named /inc/inc/hw_adc.h. If you want to keep the relative pathname inc/hw_adc.h in your #include line, and the path to the header file is /inc/hw_adc.h, then you should use just -I / (the root directory) on the compile command line.

Lastly, I'll say that I actually don't agree with Beta's suggestion that it's a bad idea to spell out paths in include lines. This is common: if you are using a library that contains a lot of header files then typically the header files are collected in a subdirectory (consider things like Boost, or X11, etc.) and it's, IMO, good practice to use the name of the subdirectory in your #include lines in the source code.

On the other hand, though, I will agree with Beta that a directory name like inc is utterly lame and is of pretty much no use whatever. That directory should have a name which is somehow evocative of the kinds of headers that can be found inside it, not something uselessly generic like "inc".

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • I agree that putting paths in `#include` directives is a *common* practice, but I still contend that it's a *bad* practice (even if I'm in the minority). *Demasiada cordura puede ser la peor de las locuras, ver la vida como es y no como debería de ser.* – Beta Dec 29 '13 at 15:01
  • I disagree completely. Having the directory there provides a namespace which is often critical. Without the directory prefix all it takes is two different libraries with a `socket.h` or `types.h` header file and you're in trouble. Collecting files in a directory is good practice, and once you have it there it's redundant to add the library name as a prefix to every file (`foobar/foobar_types.h` vs. `foobar/types.h`). – MadScientist Dec 30 '13 at 01:03
  • Wait... I think we're partly in violent agreement, at least about having separate directories of headers. I started to write my argument against paths in `#include` directives (preferring to let Make choose the directory appropriate to the source file), but realized that my approach falls flat if `baz.c` must #include both `foo/types.h` *and* `bar/types.h`. I still think that putting paths in the source code *unnecessarily* is bad, and I'm not sure that it's ever the best solution, but I must rethink this. – Beta Dec 30 '13 at 04:14