Mahmoud Saad
Mahmoud Saad

Reputation: 145

Native and cross compile using GNU make, embedded C

I'm working on a Makefile to make me able to native and cross-compile. choosing wether to compile for host linux or ti MSP432 should be done from command line:

$ make build PLATFORM=MSP432
$ make build PLATFORM=HOST

here's my Makefile that I tried to do it in:

include sources.mk

ifeq ($(PLATFORM),MSP432)
# Platform Overrides

# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = thumb
SPECS = nosys.specs

# Compiler Flags and Defines

CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
endif


ifeq ($(PLATFORM),HOST)

CC = gcc

endif


TARGET = c1m1
LDFLAGS = -Wl,-Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -Wall -Werror -g -O0  
-std=c99
CPPFLAGs =


.PHONY: build
build: $(TARGET).out


.PHONY: clean
clean:  
    rm -f $(OBJS) $(TARGET).out $(TARGET).map

%.o : %.c
$(CC) -c $< $(CFLAGS) -o $@
    OBJS = $(SOURCES:.c=.o)

$(TARGET).out: $(OBJS)
    $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $@

is this the right way to do that?

there's also another weird error happening when I compile using:

$ make main.o PLATFORM=MSP432

I get this error:

arm-none-eabi-gcc -c main.c -mcpu=cortex-m4 -mthumb -- 
specs=nosys.specs -Wall -Werror -g -O0  -std=c99 -o main.o
main.c:23:22: fatal error: platform.h: No such file or directory 
 #include "platform.h"
                  ^
compilation terminated.
Makefile:64: recipe for target 'main.o' failed
make: *** [main.o] Error 1

and when I compile using this:

$ make main.o PLATFORM=HOST

I get this error, they are 2 different errors and I can't understand the reason behind this.

gcc -c main.c -mcpu= -m --specs= -Wall -Werror -g -O0  -std=c99 -o 
main.o
gcc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ 
instead
gcc: error: missing argument to ‘-mcpu=’
gcc: error: missing argument to ‘--specs=’
gcc: error: unrecognized command line option ‘-m’
Makefile:64: recipe for target 'main.o' failed
make: *** [main.o] Error 1

I posted those apparently different questions in 1 question, because I think they are affecting eachother.

this is also another headerfile that is called platform.h that has some conditionals to include some directives, which after the answer I think might be needed for compile time switches

#ifndef __PLATFORM_H__
#define __PLATFORM_H__

#if defined (MSP432)
#include "msp432p401r.h"
#define PRINTF(...)




#elif defined (HOST)
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)



#else
#error "Platform provided is not supported in this Build System"
#endif

#endif /* __PLATFORM_H__ */

Upvotes: 4

Views: 1539

Answers (1)

Mathieu
Mathieu

Reputation: 9649

First, I will answer the case when PLATFORM and HOST are the same:

$ make main.o PLATFORM=HOST

I get this error, they are 2 different errors and I can't understand the reason behind this.

gcc -c main.c -mcpu= -m --specs= -Wall -Werror -g -O0  -std=c99 -o 
main.o
gcc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ 
instead
gcc: error: missing argument to ‘-mcpu=’
gcc: error: missing argument to ‘--specs=’
gcc: error: unrecognized command line option ‘-m’
Makefile:64: recipe for target 'main.o' failed
make: *** [main.o] Error 1

This is due to your makefile: CPU, ARCH and SPECS are only set when PLATFORM is MSP432

So the line CFLAGS = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -Wall -Werror -g -O0 -std=c99 is evalued as CFLAGS = -mcpu= -m --specs= -Wall -Werror -g -O0 -std=c99

When gcc is invoked with CFLAGS as argument, which is incorrect.

To correct this, you can make theses little changes in your makefile:

include sources.mk

ifeq ($(PLATFORM),MSP432)
# Platform Overrides

# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = thumb
SPECS = nosys.specs

LDFLAGS_ARCH = -T $(LINKER_FILE)
CFLAGS_ARCH = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS)

# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
endif

ifeq ($(PLATFORM),HOST)

CC = gcc

endif


TARGET = c1m1
LDFLAGS = -Wl,-Map=$(TARGET).map $(LDFLAGS_ARCH)
CFLAGS = $(CFLAGS_ARCH) -Wall -Werror -g -O0  
-std=c99
CPPFLAGs =

Now, for the main.c:23:22: fatal error: platform.h: No such file or directory You have to find where this file is locatted and eventually add it as a gcc option.

For instance, if the file platform.h is in /some/directory, you can add this option to gcc to help it to find it:

-I/some/directory

So in makefile, you can have this line:

CFLAGS_ARCH = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -I/some/directory

EDIT

In comments, you add this problem for your question:

that solved it the errors are consistent now, and here it is

 In file included from main.c:23:0: ./include/common/platform.h:30:2: error:
 #error "Platform provided is not supported in this Build System" #error "... *** [main.o] Error 1 

Regarding the platform.h file, macro MSP432 or HOST must be defined in order to run.

To define such macro, the -D option must be passed to gcc.

So the idea is to add some line to the makefile to define MSP432 or HOST when necessary:

...
ifeq ($(PLATFORM),MSP432)
# Platform Overrides

# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = thumb
SPECS = nosys.specs

LDFLAGS_ARCH = -T $(LINKER_FILE)
CFLAGS_ARCH = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -DMSP432 

# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
endif

ifeq ($(PLATFORM),HOST)

CFLAGS_ARCH = -DHOST 

CC = gcc

endif
...

Upvotes: 2

Related Questions