Here are minimalist makefiles for app&lib generation

Hi,

for those of you who prefer old-fashioned, basic, easily customizable GNU makefiles, here are some minimalist versions to hack to your heart’s content. They will respectively generate an Open AT application, and an Open AT library. Notice that these versions:

  • require some variable settings and filenames listing in the makefile
  • use the ADS compiler, not GCC [Update: Matt Otto fixed this, see post below] nor RTE yet
  • still require an installation of the SDK, as they run some executables provided by it
  • are designed to run at the root of your project application/library
  • are not recursive: if one project depends on another lib, and you change something in that lib, it’s up to you to recompile the lib before the project depending on it. Again, the goal is to K.I.S.S., so if you want somthing fancier, DIY!

If you feel like improving/completing these, here’s the dirty little secret: in $(OATROOT)/IDE/IDE/$(IDEVERSION)/make/gen.mak, comment the first uncommented line “.SILENT:”. This way you’ll have every single executed command printed on the output, together with the usual logs. Save these, and check what your specific configuration does. Your contributions are obviously welcome on this thread.

Now the application generation makefile:

# Name of the resulting application, without extension
APP_NAME    = luasample

# Basic paths and version numbers;
# can be retrieved from the "Open AT IDE Settings" GUI application
OAT_ROOT    = c:/OpenAT-oasis-201
OS_VERSION  = 6.01.05
IDE_VERSION = 1.06.04
WIP_VERSION = 4.00.2050
OAT_API_VERSION = 602

# Paths to Open AT header files
INCLUDES = \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/itf \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/basic \
	-I$(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/itf \

# Paths to local header files
INCLUDES += \
	-Iitf \
	-Iinc \

# Paths to other user-defined library headers
INCLUDES += \
	-Id:/fft/src/git/oatlua/itf \

# All source files of this project (excluding libraries)
SRC = appli.c

# Paths where source files might be found (relative or absolute, space-separated)
VPATH = src

# C compiler settings
CC     = M:/ads/ADS_V12/Bin/tcc
CFLAGS = -D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -apcs /noswstackcheck/interwork -Ono_data_reorder -Wbnsu+adefgiklmopvx -Ecz -O2 -cpu ARM946E-S -g

# C linker settings for application generation
# LINK_RWBASE = 0x180C0000 # For  8Mb RAM modules
LINK_RWBASE = 0x18100000 # For 16Mb RAM modules
LINK_FLAGS    = -ro 0x00220000 -rw-base $(LINK_RWBASE) -first mos_header.o\(OAT_HEADER_AREA\) -elf -info sizes -info unused -xref -verbose -noremove

# Various tools, either from Open AT or from ADS
FROMELF  = M:/ads/ADS_V12/Bin/fromelf
ADDCHECK = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/cygwin/addchk.exe
AXFSHRINKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/cygwin/AXFshrinker.exe 
WZPACKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/cygwin/wzpacker.exe
GENDWL   = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/cygwin/python/python.exe -E $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/scripts/gendwl.py

# Library binaries to link to the project
LIBRARIES  = $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/ads_wmadl_$(OS_VERSION).0.0.lib
LIBRARIES += $(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/ads_wmwip_$(WIP_VERSION).lib
LIBRARIES += d:/fft/src/git/oatlua/ads_oatlua.lib

# By default, build the compressed binary
all: $(APP_NAME).wpb.dwl

clean:
	$(RM) *.axf *.bin *.wpb *.o *.dwl s m

# Generation of TMT traces file. Not functional yet.
backtraces.axf: $(APP_NAME).axf
	$(AXFSHRINKER) $< $@

# Usual C compilation rule
%.o: %.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

# Link of object files and libraries
$(APP_NAME).axf: $(SRC:.c=.o)
	$(LINK) $(LINK_FLAGS) $+ $(LIBRARIES) -o $@ -list m -symdefs s -errors $(APP_NAME).link.log

# Convert linked binary into a signed .bin file
%.bin: %.axf
	$(FROMELF) $< -bin -output $@
	$(ADDCHECK) $@

# Compressed version of the .bin file
%.wpb: %.bin
	$(WZPACKER) -b 0x00220000 $<

# Non-compressed, X-MODEM downloadable of the .bin file
%.dwl: %.bin
	$(GENDWL) --bin $< --dwl $@ --addr 0x00220000 --header BINARY

# X-MODEM downloadable version of the compressed binary file
%.wpb.dwl: %.wpb
	$(GENDWL) --bin $< --dwl $@ --addr 0x00220000 --header COMPBIN

.PHONY: all clean

And the library generation Makefile:

# Name of the library, without extension
LIB_NAME = oatlua

# Basic paths and version numbers;
# can be retrieved from the "Open AT IDE Settings" GUI application
OAT_ROOT    = c:/OpenAT-oasis-201
OS_VERSION  = 6.01.05
IDE_VERSION = 1.06.04
WIP_VERSION = 4.00.2050
OAT_API_VERSION = 602

# All source files of this library
SRC = \
	lapi.c \
	lauxlib.c \
	lbaselib.c \
	lcode.c \
	ldblib.c \
	ldebug.c \
	ldo.c \
	ldump.c \
	lfunc.c \
	lgc.c \
	linit.c \
	llex.c \
	lmem.c \
	loadlib.c \
	lobject.c \
	lopcodes.c \
	lparser.c \
	lstate.c \
	lstring.c \
	lstrlib.c \
	ltable.c \
	ltablib.c \
	ltm.c \
	lundump.c \
	lvm.c \
	lzio.c \
	luaw_at.c \
	luaw_b64md5.c \
	luaw_bearers.c \
	luaw_channel.c \
	luaw_core.c \
	luaw_flash.c \
	luaw_int.c \
	luaw_main.c \
	luaw_mem.c \
	luaw_options.c \
	luaw_sms.c \
	luaw_sync.c \
	luaw_tcp.c \
	luaw_timer.c

# Paths where source files might be found (relative or absolute, space-separated)
VPATH = src_porting src_orig

# Paths to Open AT header files
INCLUDES = \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/itf \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/basic \
	-I$(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/itf \

# Paths to local header files
INCLUDES += \
	-Iitf \
	-Iinc \

# C compiler settings
CC     = M:/ads/ADS_V12/Bin/tcc
CFLAGS = -D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -apcs /noswstackcheck/interwork -Ono_data_reorder -Wbnsu+adefgiklmopvx -Ecz -O2 -cpu ARM946E-S -g

# Linker settings for library generation 
AR = M:/ads/ADS_V12/Bin/armar

all: ads_$(LIB_NAME).lib

clean:
	$(RM) *.o *.lib

# Generation of the library
ads_$(LIB_NAME).lib: $(SRC:.c=.o)
	$(AR) -create $@ $+

# Usual C compilation rule
%.o: %.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

.PHONY: all clean

Thanks fft! I’ve been planning on doing this ever since I migrated my development to Linux, but I never did. This was just the kick in the pants I needed.

I’ve taken your application Makefile and ported it to my environment, which has three big differences:

  • Works with Cygwin or Linux
  • Uses GCC
  • Uses OpenAT SDK 4.24d

Each of these differences meant different tweaks.

Here’s the Makefile

# Name of the resulting application, without extension
APP_NAME    = gccsample

# Basic paths, supporting Cygwin and Linux
ifeq ($(OSTYPE), cygwin)
OS = cygwin
OAT_ROOT = C:/OpenAT
GCC_ROOT = $(OAT_ROOT)/IDE/GCC/4.0.1.1
else
OS = linux
OAT_ROOT = $(HOME)/OpenAT
GCC_ROOT = /usr/local
endif

# Version numbers
OS_VERSION  = 4.22.00
IDE_VERSION = 1.04.07
WIP_VERSION = 3.10.2034
GCC_VERSION = 4.0.1

#
# With luck, you shouldn't need to edit anything below here.
#

# use the first two parts of the version, and remove the period between them
OAT_API_VERSION = $(word 1, $(subst ., ,$(OS_VERSION)))$(word 2, $(subst ., ,$(OS_VERSION)))
WIP_PLUGIN_VERSION = $(word 1, $(subst ., ,$(WIP_VERSION)))$(word 2, $(subst ., ,$(WIP_VERSION)))

# Paths to Open AT header files
INCLUDES = \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/itf \
	-I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/basic \
	-I$(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/itf \
	-I$(GCC_ROOT)/lib/gcc/arm-elf/$(GCC_VERSION)/include \
	-I$(GCC_ROOT)/arm-elf/include \
	-I$(GCC_ROOT)/arm-elf/sys-include

# Paths to local header files
INCLUDES += \
   -Iitf \
   -Iinc \

# Paths to other user-defined library headers
INCLUDES +=

# Paths where source files might be found (relative or absolute, space-separated)
VPATH = src

# Either list all source files of this project (excluding libraries),
# or use the second option, which automatically uses all .c files in VPATH
#SRC = appli.c
SRC := $(notdir $(foreach dir, $(VPATH), $(wildcard $(dir)/*.c)))

# C compiler settings
CC     = $(GCC_ROOT)/bin/arm-elf-gcc
CC_COMMON_FLAGS = -Os -O2 -fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -ggdb3 -nostdinc -march=armv5te
CFLAGS = -D__WIP_PLUGIN_VERSION__=$(WIP_PLUGIN_VERSION) -D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -D__arm -D__GNU_GCC__  $(CC_COMMON_FLAGS)

# C linker settings for application generation
LINK       = $(GCC_ROOT)/bin/arm-elf-gcc
LINK_FLAGS = $(CC_COMMON_FLAGS) -Wl,--script,linker.opt,--nmagic,-Map,mapfile

# GCC tools
AR = $(GCC_ROOT)/bin/arm-elf-ar
OBJCOPY = $(GCC_ROOT)/bin/arm-elf-objcopy

# Various tools, from Open AT
ADDCHECK = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/addchk
AXFSHRINKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/AXFshrinker
WZPACKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/wzpacker
GENDWL   = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/genbin

# Library binaries to link to the project
LIBRARIES  = $(wildcard $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/gcc_wmadl_*.lib)
LIBRARIES += $(wildcard $(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/gcc_wmwip_*.lib)

# By default, build the compressed binary
all: $(APP_NAME).wpb.dwl

clean:
	$(RM) *.axf *.elf *.bin *.wpb *.o *.dwl s mapfile opec_header.o genBin.trc

# Generation of TMT traces file. Not functional yet.
backtraces.axf: $(APP_NAME).elf
	$(AXFSHRINKER) $< $@

# Usual C compilation rule
%.o: %.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

opec_header.o:
	$(AR) -x $(wildcard $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/gcc_wmadl_*.lib) $@

# Link of object files and libraries
$(APP_NAME).elf: $(SRC:.c=.o) opec_header.o
	$(LINK) $(LINK_FLAGS) $+ $(LIBRARIES) -o $@

# Convert linked binary into a signed .bin file
# the first four lines were copied from the Linux version of fromelf
%.bin: %.elf
	$(OBJCOPY) --strip-all --strip-debug --strip-unneeded --discard-all --weaken $*.elf $*.tmp || (RVAL=$$?; rm -f $*.tmp; exit $$RVAL)
	$(OBJCOPY) --output-target binary $*.tmp $*.tmp2 || (RVAL=$$?; rm -f $*.tmp $*.tmp2; exit $$RVAL)
	dd if=$*.tmp2 of=$*.bin bs=4 conv=sync || (RVAL=$$?; rm -f $*.tmp $*.tmp2; exit $$RVAL)
	rm -f $*.tmp $*.tmp2
	$(ADDCHECK) $@

# Compressed version of the .bin file
%.wpb: %.bin
	$(WZPACKER) -b 0x00210000 $<

# Non-compressed, X-MODEM downloadable of the .bin file
%.dwl: %.bin
	$(GENDWL) -bin $< -dwl $@ -adr 0x00210000

# X-MODEM downloadable version of the compressed binary file
%.wpb.dwl: %.wpb
	$(GENDWL) -bin $< -dwl $@ -adr 0x00210000 -header BINCOM

.PHONY: all clean

And OpenAT uses a linker script when using GCC, so here’s one that was autogenerated by OpenAT (this should work for any 256kB project):

/* The linker command script */

/* Set the entry point */
ENTRY    (opec_cusBinHeader)


/* Set the memory mapping */
MEMORY
{

   ROM_MAP (rx)   : ORIGIN = 0x00210000, LENGTH = 8192k
   RAM_MAP (!rx)  : ORIGIN = 0x180C0000, LENGTH = 8192k

}

SECTIONS
{
   .oat_header :
   {
      opec_header.o ( .rodata* )
   } > ROM_MAP

   .text :
   {
      /* define the value of the begin of code section */
      PROVIDE(Image$$RO$$Base = .);
      *( .text )
      *( .rodata* )
      /* define the value of the end of code section */
      PROVIDE(Image$$RO$$Limit = .);
      /* define the length of the code section */
      PROVIDE(Image$$ER_RO$$Length = SIZEOF(.text));
      _etext = .;
   } > ROM_MAP

  .data : AT (_etext)
   {
      /* define the value of the begin of data initialised section */
      PROVIDE(Image$$RW$$Base = .);
      *( .data )
      /* define the value of the end of data initialised section */
      PROVIDE(Image$$RW$$Limit = .);
      /* define the length of the data initialised section */
      PROVIDE(Image$$ER_RW$$Length = SIZEOF(.data));
   } > RAM_MAP

   .bss :
   {
      /* define the value of the begin of data zero initialised section */
      PROVIDE(Image$$ZI$$Base = .);
      *( .bss )
      *( COMMON )
      /* define the value of the end of data zero initialised section */
      PROVIDE(Image$$ZI$$Limit = .);
      PROVIDE(end = .);
      /* define the length of the data zero initialised section */
      PROVIDE(Image$$ER_ZI$$ZI$$Length = SIZEOF(.bss));
   } > RAM_MAP

   . = ALIGN(4);
}

If you substitute 180C0000 with 18100000, it should work on 16Mb modules. I’m interested in success reports :slight_smile:

Just a heads-up that I’ve updated my Makefile (posted above). It now works in Cygwin as well as Linux, I updated to SDK 4.24d, and I did some cleaning of my previous mess.

I made my own version of this long before I came across this post, and mine does support RTE.

Mine is made to work under Cygwin, but it shouldn’t be too hard to make it work under Linux.

I’ve separated it into a global Makefile (which is pretty sparse), Makefile.target (Target mode), and Makefile.rte (RTE mode). You should never have to modify Makefile.target or Makefile.rte.

Modify outscript.ld as specified earlier.

To build normally with GCC in target mode

make -j3

To build with ADS in target mode (Doesn’t actually work yet, still working on it. Also, can’t use jobs due to licensing issues.)

make ADS=true -j1

To build in RTE mode

make RTE=true

To debug in target mode via JTAG (Designed to use SEGGER J-Link GDB Server)

make debug

To debug in RTE mode

make RTE=true debug

If you run either debug from an X terminal, it will use ddd instead of gdb.

One last note: The OpenAT IDE, when compiling, searches for any CustomStackSize variables, and multiplies them by 3.

Makefile:

CPPFLAGS=-Iinc
SOURCES=$(wildcard src/*.c)

## Name of output
TARGET=test

## Uncomment the following to enable Plug-Ins
#WIP=4.00.2080
#SECURITY=1.00.2030
#CGPS=1.06.2000
OAT_API_VERSION=601
OAT_OS_VERSION=6.01.07
OAT_IDE_VERSION=1.06.04
OAT_GCC_VERSION=4.0.1.2
GCC_VERSION=4.0.1

#optimize for size
BUILD=

#optimize for debugging
#BUILD=debug

ifeq ($(RTE),true)
include Makefile.rte
else
include Makefile.target
endif

Makefile.rte

CC=gcc

CFLAGS=-D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -D__arm -D__GNU_GCC__ -O0 -fshort-enums -fomit-frame-pointer -g3 -mno-cygwin
CFLAGS+=-I/cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/itf
CFLAGS+=-I/cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/basic

LDFLAGS+=-O0 -g3 -shared -mno-cygwin
LDFLAGS+=/cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/rte_wmadl_$(OAT_OS_VERSION).0.0.lib

ifneq ($(SECURITY),)
CFLAGS+=-I/cygdrive/c/OpenAT/Plug-ins/Security/$(SECURITY)/Security/itf
LDFLAGS+=$(wildcard /cygdrive/c/OpenAT/Plug-ins/Security/$(SECURITY)/Security/rte_wmwipssl_*.lib)
LDFLAGS+=$(wildcard /cygdrive/c/OpenAT/Plug-ins/Security/$(SECURITY)/Security/rte_wmjam_*.lib)
endif

ifneq ($(WIP),)
CFLAGS+=-I/cygdrive/c/OpenAT/Plug-ins/WIP/$(WIP)/WIP/itf
LDFLAGS+=$(wildcard /cygdrive/c/OpenAT/Plug-ins/WIP/$(WIP)/WIP/rte_wmwip_*.lib)
endif

ifneq ($(CGPS),)
CFLAGS+=-I/cygdrive/c/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/itf
LDFLAGS+=$(wildcard /cygdrive/c/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/rte_CGPS_*.lib)
endif

ifeq ($(BUILD),debug)
CFLAGS+=-g3 -O0
else
CFLAGS+=-Os
endif

OBJECTS=$(SOURCES:.c=.o)

default: tags rte/OatAppli.dll rte/kernel.exe

tags: $(SOURCES)
	ctags $(SOURCES)

rte/OatAppli.dll: $(OBJECTS)
	$(CC) -o $@ $(OBJECTS) $(LDFLAGS)

rte/kernel.exe: /cygdrive/c/OpenAT/Firmware/R71_00/rte_Kernel.exe
	cp $< $@

clean:
	rm -f $(TARGET).* mos_header.o $(OBJECTS) rte/OatAppli.dll

debug:
	echo file rte/OatAppli.dll > .gdbinit
	echo exec-file rte/kernel.exe >> .gdbinit
	echo target remote :2331 >> .gdbinit
ifeq ($(DISPLAY),)
	gdb
else
	arm-elf-gdb
endif
	rm .gdbinit

Makefile.target

ifeq ($(ADS),)
CC=arm-elf-gcc
COMPILERNAME=gcc
else
CC=tcc
COMPILERNAME=ads
endif

ifeq ($(ADS),)
CFLAGS+=-fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -nostdinc -march=armv5te -nodefaultlibs
CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/arm-elf/include
CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/lib/gcc/arm-elf/$(GCC_VERSION)/include
else
CFLAGS+=-cpu 5te -apcs /interwork
endif
CFLAGS+=-IC:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/itf
CFLAGS+=-IC:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/basic
CFLAGS+=-D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -D__arm -D__GNU_GCC__

ifeq ($(ADS),)
#Not sure these libs are necessary
#LDFLAGS+=-LC:/OpenAT/IDE/GCC/4.0.1.1/arm-elf/lib/interwork
LDFLAGS+=-fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -nostdinc -march=armv5te
LDFLAGS+=-Wl,--script,outscript.ld,-v,--print-map,--nmagic,--verbose,--trace,-Map,m
LDFLAGS+=-Wl,-\(
endif
LDFLAGS+=C:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/$(COMPILERNAME)_wmadl_$(OAT_OS_VERSION).0.0.lib

ifneq ($(SECURITY),)
CFLAGS+=-IC:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/itf
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/$(COMPILERNAME)_wmwipssl_*.lib)
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/$(COMPILERNAME)_wmjam_*.lib)
endif

ifneq ($(WIP),)
CFLAGS+=-IC:/OpenAT/Plug-ins/WIP/$(WIP)/WIP/itf
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/WIP/$(WIP)/WIP/$(COMPILERNAME)_wmwip_*.lib)
endif

ifneq ($(CGPS),)
CFLAGS+=-IC:/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/itf -D__CGPS_PLUGIN_VERSION__=$(CGPS_PLUGIN_VERSION)
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/$(COMPILERNAME)_CGPS_*.lib)
endif

ifeq ($(ADS),)
LDFLAGS+=-Wl,-\)
endif

ifeq ($(BUILD),debug)
ifeq ($(ADS),)
CFLAGS+=-g3 -O0
else
CFLAGS+=-g -O0
endif
else
ifeq ($(ADS),)
CFLAGS+=-Os -O2
else
CFLAGS+=-Ospace
endif
endif

OBJECTS=$(SOURCES:.c=.o)

default: tags $(TARGET).dwl $(TARGET).wpb.dwl

tags: $(SOURCES)
	ctags $(SOURCES)

$(TARGET).elf: $(OBJECTS) mos_header.o outscript.ld
	$(CC) -o $@ $(CFLAGS) $(OBJECTS) $(LDFLAGS)

%.bin: %.elf
	arm-elf-objcopy.exe --strip-all --strip-debug --strip-unneeded --discard-all --weaken --output-target binary $< $<.tmp
	dd if=$<.tmp of=$@ bs=4 conv=sync 2>> $@_fromelf.err
	/cygdrive/c/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/addchk $@

%.wpb: %.bin
	/cygdrive/c/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/wzpacker.exe -b 0x00220000 $< $@
	
%.dwl: %.bin
	C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/python/python.exe C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/scripts/gendwl.py --bin=$< --dwl=$@ --header=BINARY --addr 0x00220000

%.wpb.dwl: %.wpb
	C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/python/python.exe C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/scripts/gendwl.py --bin=$< --dwl=$@ --header=COMPBIN --addr 0x00220000

mos_header.o: /cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/gcc_wmadl_$(OAT_OS_VERSION).0.0.lib
	arm-elf-ar x /cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/gcc_wmadl_$(OAT_OS_VERSION).0.0.lib mos_header.o
	
clean:
	rm -f $(TARGET).* mos_header.o $(OBJECTS)

debug: $(TARGET).elf
	echo file $(TARGET).elf > .gdbinit
	echo target remote :2331 >> .gdbinit
ifeq ($(DISPLAY),)
	arm-elf-gdb
else
	ddd --debugger arm-elf-gdb
endif
	rm .gdbinit

outscript.ld

/* The linker command script */

/* Set the entry point */
/* ENTRY    (opec_cusBinHeader)   */
ENTRY    (mos_BinHeader)   


/* Set the memory mapping */
MEMORY 
{
   ROM_MAP (rx)   : ORIGIN = 0x00220000, LENGTH = 8192k
/* 1MB+ Memory */
   RAM_MAP (!rx)  : ORIGIN = 0x18100000, LENGTH = 8192k
/* 256K Memory */
/*   RAM_MAP (!rx)  : ORIGIN = 0x180C0000, LENGTH = 8192k */

}
PHDRS
{
   appli PT_LOAD ;
}

SECTIONS
{
   .oat_header :
   {
      mos_header.o ( .rodata* )
   } > ROM_MAP :appli
   
   .text :
   {
      /* define the value of the begin of code section */
      PROVIDE(Image$$RO$$Base = .);
      *( .text ) 
      *( .rodata* )
      /* define the value of the end of code section */
      PROVIDE(Image$$RO$$Limit = .);
      /* define the length of the code section */
      PROVIDE(Image$$ER_RO$$Length = SIZEOF(.text));
/*      *(.glue_7t) *(.glue_7) */
      _etext = .;
   } > ROM_MAP :appli

  .data : AT (_etext)
   {
      /* define the value of the begin of data initialised section */
      PROVIDE(Image$$RW$$Base = .);
      *( .data ) 
      /* define the value of the end of data initialised section */
      PROVIDE(Image$$RW$$Limit = .);
      /* define the length of the data initialised section */
      PROVIDE(Image$$ER_RW$$Length = SIZEOF(.data));
   } > RAM_MAP :appli

   .bss :
   { 
      /* define the value of the begin of data zero initialised section */
      PROVIDE(Image$$ZI$$Base = .);
      *( .bss ) 
      *( COMMON ) 
      /* define the value of the end of data zero initialised section */
      PROVIDE(Image$$ZI$$Limit = .);
      PROVIDE(end = .);
      /* define the length of the data zero initialised section */
      PROVIDE(Image$$ER_ZI$$ZI$$Length = SIZEOF(.bss));
   } > RAM_MAP :appli
   
   . = ALIGN(4);
}

Hello,
I tried to roll my own makefile set for compiling the application I am working on. This thread is very helpful, but I still miss some bits to have the build system working.

If my application is short enough (e.g. the hello_world demo) then it works fine, but if the application is larger then it won't run on the evaluation board. Unfortunately I got no error messages from the board, rather it appears to run the last working application as if I would have not downloaded the new code.

I have got two warnings in the elf processing. First the linker reports:
warning: cannot find entry symbol opec_cusBinHeader; defaulting to 00220064

Then the obj-copy complains about:

BFD: MIDlet.tmp: warning: allocated section `.bss' not in segment

Both doesn’t prevent the build to complete with a .wpb.dwl file.

Also I am a bit confused about the ENTRY line in the linker.opt script. Sometimes it is set as “opec_cusBinHeader”, sometimes “mos_BinHeader”. What’s the difference?

Here is my linker.opt file:

/* The linker command script */

/* Set the entry point */
ENTRY    (opec_cusBinHeader)
/* ENTRY    (mos_BinHeader) */


/* Set the memory mapping */
MEMORY 
{

   ROM_MAP (rx)   : ORIGIN = 0x00220000, LENGTH = 8192k
/*   RAM_MAP (!rx)  : ORIGIN = 0x180C0000, LENGTH = 8192k */
   RAM_MAP (!rx)  : ORIGIN = 0x18100000, LENGTH = 8192k

}
PHDRS
{
   appli PT_LOAD ;
}

SECTIONS
{
   .oat_header :
   {
      mos_header.o ( .rodata* )
   } > ROM_MAP :appli
   
   .text :
   {
      /* RO and ER_RO symbols are provided for legacy OS support */
      /* define the value of the begin of code section */
      PROVIDE(Image$$APP_RO$$Base = .);
      PROVIDE(Image$$RO$$Base = .);
      *( .text ) 
      *( .rodata* )
      /* define the value of the end of code section */
      PROVIDE(Image$$APP_RO$$Limit = .);
      PROVIDE(Image$$RO$$Limit = .);
      /* define the length of the code section */
      PROVIDE(Image$$APP_RO$$Length = SIZEOF(.text));
      PROVIDE(Image$$ER_RO$$Length = SIZEOF(.text));
      _etext = .;
   } > ROM_MAP :appli

  .data : AT (_etext)
   {
      /* RW and ER_RW symbols are provided for legacy OS support */
      /* define the value of the begin of data initialized section */
      PROVIDE(Image$$APP_DATA$$Base = .);
      PROVIDE(Image$$RW$$Base = .);
      *( .data ) 
      /* define the value of the end of data initialized section */
      PROVIDE(Image$$APP_DATA$$Limit = .);
      PROVIDE(Image$$RW$$Limit = .);
      /* define the length of the data initialized section */
      PROVIDE(Image$$APP_DATA$$Length = SIZEOF(.data));
      PROVIDE(Image$$ER_RW$$Length = SIZEOF(.data));
   } > RAM_MAP :appli

   .bss :
   { 
      /* ZI symbol is provided for legacy OS support */
      /* define the value of the begin of data zero initialized section */
      PROVIDE(Image$$APP_BSS$$Base = .);
      PROVIDE(Image$$ZI$$Base = .);
      *( .bss ) 
      *( COMMON ) 
      /* define the value of the end of data zero initialized section */
      PROVIDE(Image$$APP_BSS$$Limit = .);
      PROVIDE(Image$$ZI$$Limit = .);
      /* define the length of the data zero initialized section */
      PROVIDE(Image$$APP_BSS$$ZI$$Length = SIZEOF(.bss));
      PROVIDE(Image$$ER_ZI$$ZI$$Length = SIZEOF(.bss));
   } > RAM_MAP :appli
   
   .uninit (NOLOAD) :
   {
      /* define the value of the begin of uninitialized section */
      PROVIDE(Image$$APP_UNINIT$$Base = .); 
      * (UNINIT)
      /* define the value of the end of uninitialized section */
      PROVIDE(Image$$APP_UNINIT$$Limit = .);
      PROVIDE(end = .);
      /* define the length of the uninitialized section */
      PROVIDE(Image$$APP_UNINIT$$ZI$$Length = SIZEOF(.uninit));
   } > RAM_MAP :appli
   
   . = ALIGN(4);
}

Thank you in advance for any help, suggestion, pointer.

Best Regards

Max

What Wavecom device are you trying to build for? I got my linker script right from the OpenAT SDK, so the differences in the ENTRY line may have to do with the device you’re compiling for.

I am building for WMP100.

Best Regards

Max

OK, after looking into it a little deeper, I realize that the ENTRY line doesn’t have to do with the device, so it must have to do with the SDK version. The linker file is created from IDE/IDE//xsl/mnf2lnkopt.xsl, which hard-codes the ENTRY line.

What I would recommend (this is what I did) is to use the Project Wizard to create a project that you know works (correct versions, correct memory model, etc.). Then just copy your_project/gcc/mak/linker.opt to your real makefile-based project.

Hello,
I tried to use the Makefile, and actually it works perfectly for my needings.
So I decided to try to install the whole gcc toolchain from http://www.gnuarm.com/ in order to try to compile c++ programs as well.

My Makefile became:

CPPFLAGS=-Iinc
SOURCES=$(wildcard src/*.cpp)

## Name of output
TARGET=HttpGet

## Uncomment the following to enable Plug-Ins
WIP=4.00.2081
#SECURITY=1.00.2030
#CGPS=1.06.2000
OAT_API_VERSION=602
OAT_OS_VERSION=6.02.02
OAT_IDE_VERSION=1.07.01
OAT_GCC_VERSION=4.0.1.2
GCC_VERSION=4.0.1

#optimize for size
BUILD=

#optimize for debugging
#BUILD=debug

ifeq ($(ADS),)
GCCPATH=C:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/bin
CC=$(GCCPATH)/arm-elf-g++
COMPILERNAME=gcc

else
CC=tcc
COMPILERNAME=ads
endif

ifeq ($(ADS),)
CFLAGS+=-fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -nostdinc -march=armv5te
CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/arm-elf/include
CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/arm-elf/sys-include
#CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/include/c++/$(GCC_VERSION)
#CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/include/c++/$(GCC_VERSION)/arm-elf
CFLAGS+=-IC:/OpenAT/IDE/GCC/$(OAT_GCC_VERSION)/lib/gcc/arm-elf/$(GCC_VERSION)/include
CFLAGS+=$(CPPFLAGS)
else
CFLAGS+=-cpu 5te -apcs /interwork
endif
CFLAGS+=-IC:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/itf
CFLAGS+=-IC:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/basic
CFLAGS+=-D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -D__arm -D__GNU_GCC__

ifeq ($(ADS),)
#Not sure these libs are necessary
LDFLAGS+=-LC:/OpenAT/IDE/GCC$(OAT_GCC_VERSION)/arm-elf/lib/interwork
LDFLAGS+=-fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -nostdinc -march=armv5te
LDFLAGS+=-Wl,--script,outscript.ld,-v,--print-map,--nmagic,--verbose,--trace,-Map,m
LDFLAGS+=-Wl,-\(
endif
LDFLAGS+=C:/OpenAT/OS/$(OAT_OS_VERSION)/ADL/$(COMPILERNAME)_wmadl_$(OAT_OS_VERSION).0.0.lib

ifneq ($(SECURITY),)
CFLAGS+=-IC:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/itf
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/$(COMPILERNAME)_wmwipssl_*.lib)
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/Security/$(SECURITY)/Security/$(COMPILERNAME)_wmjam_*.lib)
endif

ifneq ($(WIP),)
#CFLAGS+=-IC:/OpenAT/Plug-ins/WIP/$(WIP)/WIP/itf
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/WIP/$(WIP)/WIP/$(COMPILERNAME)_wmwip_*.lib)
endif

ifneq ($(CGPS),)
CFLAGS+=-IC:/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/itf -D__CGPS_PLUGIN_VERSION__=$(CGPS_PLUGIN_VERSION)
LDFLAGS+=$(wildcard C:/OpenAT/Plug-ins/C-GPS/$(CGPS)/C-GPS/$(COMPILERNAME)_CGPS_*.lib)
endif

ifeq ($(ADS),)
LDFLAGS+=-Wl,-\)
endif

ifeq ($(BUILD),debug)
ifeq ($(ADS),)
CFLAGS+=-g3 -O0
else
CFLAGS+=-g -O0
endif
else
ifeq ($(ADS),)
CFLAGS+=-Os -O2
else
CFLAGS+=-Ospace
endif
endif

OBJECTS=$(SOURCES:.c=.o)

default: tags $(TARGET).dwl $(TARGET).wpb.dwl

tags: $(SOURCES)
	ctags $(SOURCES)

$(TARGET).elf: $(OBJECTS) mos_header.o outscript.ld
	$(CC) -o $@ $(CFLAGS) $(OBJECTS) $(LDFLAGS)

%.bin: %.elf
	$(GCCPATH)/arm-elf-objcopy.exe --strip-all --strip-debug --strip-unneeded --discard-all --weaken --output-target binary $< $<.tmp
	dd if=$<.tmp of=$@ bs=4 conv=sync 2>> $@_fromelf.err
	/cygdrive/c/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/addchk $@

%.wpb: %.bin
	/cygdrive/c/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/wzpacker.exe -b 0x00220000 $< $@

%.dwl: %.bin
	C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/python/python.exe C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/scripts/gendwl.py --bin=$< --dwl=$@ --header=BINARY --addr 0x00220000

%.wpb.dwl: %.wpb
	C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/cygwin/python/python.exe C:/OpenAT/IDE/IDE/$(OAT_IDE_VERSION)/sgt/tools/scripts/gendwl.py --bin=$< --dwl=$@ --header=COMPBIN --addr 0x00220000

mos_header.o: /cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/gcc_wmadl_$(OAT_OS_VERSION).0.0.lib
	$(GCCPATH)/arm-elf-ar x /cygdrive/c/OpenAT/OS/$(OAT_OS_VERSION)/ADL/gcc_wmadl_$(OAT_OS_VERSION).0.0.lib mos_header.o

clean:
	rm -f $(TARGET) mos_header.o $(OBJECTS)

debug: $(TARGET).elf
	echo file $(TARGET).elf > .gdbinit
	echo target remote :2331 >> .gdbinit
ifeq ($(DISPLAY),)
	arm-elf-gdb
else
	ddd --debugger arm-elf-gdb
endif
	rm .gdbinit

I realized that I could use just some of the c++ features because the linker.opt don’t contain sections that C++ needs: i.e. .ctors and .dtors, for constructors and destructors. (I don’t know how to change that file and maybe it’s not possible to add other sections…)

So:

  • No constructors or destructors
  • Templates don’t work as well, because they “overlap” the .data section.
  • No stl support.
  • Not compatible with some plugins, WIP, i.e.

The minimal c++ support is limited to operator overloading, classes without constructors (maybe overloading the new operator we could do something), polymorphism.
Just enough to considering it, BTW. :wink:

Then, when I tried to compile an example that links the wip library and I realized that I had to change some headers in order to compile the http_get example. It compiles, it runs, but it doesn’t connect.
I don’t know what can I do in order to see if there’s a way to let the WIP to connect and actually run correctly.

Without WIP my applications are useless, so I have to return to the C99 of the original toolchain.
At least until someone could find a way to run correctly a wip application.
Do you think it could be possible?

Have fun! :smiley:


fabrizio cornelli

It is possible. Here’s the manual for LD, the linker:
sourceware.org/binutils/docs/ld/index.html
Here’s the scripts section:
sourceware.org/binutils/docs/ld/ … ml#Scripts

Why not? I use WIP without any problems.

Interesting…
Can you use constructors, destructors and templates as well ? :open_mouth:

I don’t know.
I tested it only once with g++, the program runs, tries to connect to gprs but fails.
The same program compiled with gcc runs correctly.

I could try to use a different version of wip, a newer one and maybe a different example, to see what happens…
Maybe it’s just a compile error, I had to fix few headers in order to compile it… :unamused:

In conclusion, what limits do you see in c++ developing on q26*? :slight_smile:

Thank you.

fabrizio cornelli

None. You should be able to create a linker script that allows for all C++ features (including constructors, destructors and templates).

I would also be very interested in a c++ linker script. Some people posted that they were able to compile c++ a long time ago. Maybe we could succeed in creating this makefile in a joint effort?

Best regards,

wismo_coder

I have tried using the C++ make file posted above and working out various issues with my extremely minimal linux knowledge, but to no avail. At best I get “*** No rule to make target” errors from make, and poking around seems to show that this error could indicate any one or more of dozens of problems.

If someone has C++ working (even without the .ctors and .dtors), I’m sure the whole community would greatly appreciate a post of all relevant (changed) files or a more detailed explanation of what modifications are necessary.

We’ve worked out the rule problems for the most part, and boiled it down to one problem: We don’t have outscript.ld

My poor knowledge of Linux environments tells me I won’t be able to construct this script from scratch.

I’d very much like to know:
a) Where have you gentlemen been getting outscript.ld from? Did you write it yourselves?
b) Would it be possible to post your .ld script (C++ support would be nice, but not entirely necessary)?

I imagine a template or example .ld would be very helpful to others as well.

Thanks!

Are you saying that you need an outscript.ld in addition to the linker script I posted already? (See the second post in this thread.) I only needed that one script to build (which, as I said in that post, I copied from OpenAT).

Well, I had sort of forgotten about the script you posted, but as it turns out there are a few problems

  • Where did this get autogenerated from and what was it called? I found only “redboot.ld” or similar scripts lying around, and those didn’t work for me.
  • That script needs “opec_header.o” which for whatever reason is not created in my sample project. It is, however, created in some other projects on an older version of OpenAT, though I imagine the difference is not the SDK version but the contents of these projects. Suffice it to say if the script is generated and opec_header.o isn’t/shouldn’t be made for that project the .ld probably won’t require it, so it’s back to knowing where the script comes from or is supposed to come from.
  • I have serious pathing issues related to cygwin. Anything that uses /cygdrive/ simply cannot be found, and I imagine this is due to some conflict or problem with the various cygwin installations on my system. Up to this point I’ve been able to hard-code everything in the DOS-usable “c:…” format, but obviously if this is an easily fixed problem it’d be better not to have to do this for files that are generated.

Obviously it’s not your job or anyone else’s on this forum to fix these problems for me, but if you could let me know where/how you got that script I can probably get the ball rolling on my end again.

Thanks a lot.

Update: Binary compares show that all the opec_header.o files I have are the same, so I’m just copying that over, too. Now I just have to figure out why ‘ld’ returns an error code without telling me why (just lists a bunch of files that it tried to find, then found, and then exits with an error code). I’m very close to wiping all cygwin and OpenAT installations and starting from scratch, because I’m fairly certain some of these things are conflicts or bad modularity.

Here’s how opec_header.o gets generated (from my Makefile):

opec_header.o:
   $(AR) -x $(wildcard $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/gcc_wmadl_*.lib) $@

The simple description is that it’s an object in the gcc_wmadl_*.lib file, and the ‘ar’ tool extracts if from the library.

I got the linker script by building a sample project following the OpenAT-prescribed way (i.e. Windowes, cygwin, wmmake). Then I copied the linker.opt from out/gcc/ (or something like that). While I was working on porting from Windows to Linux (viewtopic.php?f=19&t=2133), I wanted to automate this somehow, but I discovered that OpenAT goes through a lot of complicated steps to generate it (including XML templates and relying on information generated by wmnew). It got too complicated, so I just copied it from a sample project and moved on.