[Tutorial][Advanced]4.CLI building on GNU/Linux/Unix

NOTE: This is a little older now and the Makefile may have problems with the new PokittoLib version. These can usually be easily fixed, just expect you may encounter some issues.

This is somewhat untidy how-to of my Linux CLI workflow, based on @FManga’s Makefile. It’s intended for GNU/Linux people who already know how to build programs using gcc and want to do it the same way with Pokitto.

UPDATE 2:

Instead of Makefile you can now use my Bash script or @Pharap’s Lua script.

Building

You can use GNU ARM Toolchain to build programs for Pokitto in a similar way you’re used to buildinging your ordinary PC programs. To set up a project, do this:

  1. Download GNU ARM toolchain binaries from here (Linux64-bit) and extract the archive to some folder (let’s say ~/gtc). (Your package manager may offer another way of installing these, but here we’ll suppose you downloaded the archive.)
  2. Similarly, download PokittoLib in some folder (let’s say ~/git/PokittoLib). It’s convenient to do it with git, as you’ll be able to update it with just git pull:
    git clone https://github.com/pokitto/PokittoLib.git
  3. Now create a folder for your project (let’s say ~/git/mygame).
  4. In that folder, do the following:
    1. Create an empty file named mbed_config.h. It has to be there.
    2. Create an empty file named My_settings.h. (Later you can specify some project specific settings in this file, such as the screen mode.)
    3. Create a symbolic link named PokittoLib to PokittoLib’s subfolder Pokitto (not the PokittoLib itself!):
      ln -s ~/git/PokittoLib/Pokitto ./PokittoLib
    4. Create a symbolic link named gtc to GNU Arm Toolchain’s bin subfolder:
      ln -s ~/gcc-arm-none_eabi-7-2018-q2-update/bin/ ./gtc
    5. Create your project’s cpp and hpp source files. You can test this with a single file named main.cpp into which you paste this:
code
#include "Pokitto.h"

Pokitto::Core pokitto;

int main()
{
pokitto.begin(); 
pokitto.setFrameRate(60);

int x = 0;

while (pokitto.isRunning())
{
  if (pokitto.update())
  {
    pokitto.display.clear();
    pokitto.display.setCursor(1,1);
    pokitto.display.print(x);
    ++x;
  }
}

return 0;
}
  1. Create a file named Makefile with this content (watch out, the tabs must not be replaced with spaces!):
code
# add files to be compiled

OBJECTS += main.o

###############################################################################
# Boiler-plate

# cross-platform directory manipulation
ifeq ($(shell echo $$OS),$$OS)
    MAKEDIR = if not exist "$(1)" mkdir "$(1)"
    RM = rmdir /S /Q "$(1)"
else
    MAKEDIR = '$(SHELL)' -c "mkdir -p \"$(1)\""
    RM = '$(SHELL)' -c "rm -rf \"$(1)\""
endif

OBJDIR := BUILD
# Move to the build directory
ifeq (,$(filter $(OBJDIR),$(notdir $(CURDIR))))
.SUFFIXES:
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
MAKETARGET = '$(MAKE)' --no-print-directory -C $(OBJDIR) -f '$(mkfile_path)' \
		'SRCDIR=$(CURDIR)' $(MAKECMDGOALS)
.PHONY: $(OBJDIR) clean
all:
	+@$(call MAKEDIR,$(OBJDIR))
	+@$(MAKETARGET)
$(OBJDIR): all
Makefile : ;
% :: $(OBJDIR) ; :
clean :
	$(call RM,$(OBJDIR))

else

# trick rules into thinking we are in the root, when we are in the bulid dir
VPATH = ..

# Boiler-plate
###############################################################################
# Project settings

PROJECT := game

# Project settings
###############################################################################
# Objects and Paths

OBJECTS += PokittoLib/POKITTO_CORE/FONTS/TIC806x6.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/ZXSpec.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/adventurer12x16.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/donut7x10.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/dragon6x8.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/font3x3.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/font3x5.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/font5x7.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/fontC64.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/fontC64UIGfx.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/fontMonkey.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/karateka8x11.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/koubit7x7.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/mini4x6.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/runes6x8.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/tight4x7.o
OBJECTS += PokittoLib/POKITTO_CORE/FONTS/tiny5x7.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palAction.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palCGA.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palDB16.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palDefault.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palGameboy.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palMagma.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palMono.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palPico.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palRainbow.o
OBJECTS += PokittoLib/POKITTO_CORE/PALETTES/palZXSpec.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoBacklight.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoBattery.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoButtons.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoConsole.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoCore.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoDisk.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoDisplay.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoFramebuffer.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoItoa.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoLogos.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoPalette.o
OBJECTS += PokittoLib/POKITTO_CORE/PokittoSound.o
OBJECTS += PokittoLib/POKITTO_HW/HWButtons.o
OBJECTS += PokittoLib/POKITTO_HW/HWLCD.o
OBJECTS += PokittoLib/POKITTO_HW/HWSound.o
OBJECTS += PokittoLib/POKITTO_HW/PokittoClock.o
OBJECTS += PokittoLib/POKITTO_HW/PokittoHW.o
OBJECTS += PokittoLib/POKITTO_HW/Pokitto_extport.o
OBJECTS += PokittoLib/POKITTO_HW/SoftwareI2C.o
OBJECTS += PokittoLib/POKITTO_HW/clock_11u6x.o
OBJECTS += PokittoLib/POKITTO_HW/dma_11u6x.o
OBJECTS += PokittoLib/POKITTO_HW/iap.o
OBJECTS += PokittoLib/POKITTO_HW/timer_11u6x.o
OBJECTS += PokittoLib/POKITTO_HW/asm/mode2.o
#OBJECTS += PokittoLib/POKITTO_LIBS/ImageFormat/BmpImage.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_envfuncs.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_helpers.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_mixfuncs.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_oscfuncs.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_songfuncs.o
OBJECTS += PokittoLib/POKITTO_LIBS/Synth/Synth_wavefuncs.o
OBJECTS += PokittoLib/POKITTO_XTERNALS/Arduino/delay.o
OBJECTS += PokittoLib/libpff/mmc.o
OBJECTS += PokittoLib/libpff/pff.o
OBJECTS += PokittoLib/mbed-pokitto/common/BusIn.o
OBJECTS += PokittoLib/mbed-pokitto/common/BusInOut.o
OBJECTS += PokittoLib/mbed-pokitto/common/BusOut.o
OBJECTS += PokittoLib/mbed-pokitto/common/CAN.o
OBJECTS += PokittoLib/mbed-pokitto/common/CallChain.o
OBJECTS += PokittoLib/mbed-pokitto/common/Ethernet.o
OBJECTS += PokittoLib/mbed-pokitto/common/FileBase.o
OBJECTS += PokittoLib/mbed-pokitto/common/FileLike.o
OBJECTS += PokittoLib/mbed-pokitto/common/FilePath.o
OBJECTS += PokittoLib/mbed-pokitto/common/FileSystemLike.o
OBJECTS += PokittoLib/mbed-pokitto/common/I2C.o
OBJECTS += PokittoLib/mbed-pokitto/common/I2CSlave.o
OBJECTS += PokittoLib/mbed-pokitto/common/InterruptIn.o
OBJECTS += PokittoLib/mbed-pokitto/common/InterruptManager.o
OBJECTS += PokittoLib/mbed-pokitto/common/LocalFileSystem.o
OBJECTS += PokittoLib/mbed-pokitto/common/RawSerial.o
OBJECTS += PokittoLib/mbed-pokitto/common/SPI.o
OBJECTS += PokittoLib/mbed-pokitto/common/SPISlave.o
OBJECTS += PokittoLib/mbed-pokitto/common/Serial.o
OBJECTS += PokittoLib/mbed-pokitto/common/SerialBase.o
OBJECTS += PokittoLib/mbed-pokitto/common/Stream.o
OBJECTS += PokittoLib/mbed-pokitto/common/Ticker.o
OBJECTS += PokittoLib/mbed-pokitto/common/Timeout.o
OBJECTS += PokittoLib/mbed-pokitto/common/Timer.o
OBJECTS += PokittoLib/mbed-pokitto/common/TimerEvent.o
OBJECTS += PokittoLib/mbed-pokitto/common/assert.o
OBJECTS += PokittoLib/mbed-pokitto/common/board.o
OBJECTS += PokittoLib/mbed-pokitto/common/error.o
OBJECTS += PokittoLib/mbed-pokitto/common/gpio.o
OBJECTS += PokittoLib/mbed-pokitto/common/lp_ticker_api.o
OBJECTS += PokittoLib/mbed-pokitto/common/mbed_interface.o
OBJECTS += PokittoLib/mbed-pokitto/common/pinmap_common.o
OBJECTS += PokittoLib/mbed-pokitto/common/retarget.o
OBJECTS += PokittoLib/mbed-pokitto/common/rtc_time.o
OBJECTS += PokittoLib/mbed-pokitto/common/semihost_api.o
OBJECTS += PokittoLib/mbed-pokitto/common/ticker_api.o
OBJECTS += PokittoLib/mbed-pokitto/common/us_ticker_api.o
OBJECTS += PokittoLib/mbed-pokitto/common/wait_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM/TARGET_LPC11U68/startup_LPC11U68.o
OBJECTS += PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/cmsis_nvic.o
OBJECTS += PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/system_LPC11U6x.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_irq_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pinmap.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/rtc_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/serial_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/sleep.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/spi_api.o
OBJECTS += PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X/us_ticker.o

INCLUDE_PATHS += -I../:
INCLUDE_PATHS += -I../.
INCLUDE_PATHS += -I../PokittoLib
INCLUDE_PATHS += -I../PokittoLib/POKITTO_CORE
INCLUDE_PATHS += -I../PokittoLib/POKITTO_CORE/FONTS
INCLUDE_PATHS += -I../PokittoLib/POKITTO_CORE/PALETTES
INCLUDE_PATHS += -I../PokittoLib/POKITTO_HW
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/ImageFormat
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/Synth
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/LibAudio
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/File
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/LibLog
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/LibSchedule
INCLUDE_PATHS += -I../PokittoLib/POKITTO_LIBS/MemOps
INCLUDE_PATHS += -I../PokittoLib/POKITTO_XTERNALS
INCLUDE_PATHS += -I../PokittoLib/POKITTO_XTERNALS/Arduino
INCLUDE_PATHS += -I../PokittoLib/libpff
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/api
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/common
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/hal
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM/TARGET_LPC11U68
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TOOLCHAIN_GCC
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/hal
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP
INCLUDE_PATHS += -I../PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X

LIBRARY_PATHS :=
LIBRARIES :=
LINKER_SCRIPT ?= ../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM/TARGET_LPC11U68/LPC11U68.ld

# Objects and Paths
###############################################################################
# Tools and Flags

AS      = '../gtc/arm-none-eabi-gcc' '-x' 'assembler-with-cpp' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-O3' '-g1' '-DMBED_RTOS_SINGLE_THREAD' '-mcpu=cortex-m0plus' '-mthumb'
CC      = '../gtc/arm-none-eabi-gcc' '-std=gnu99' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-O3' '-g1' '-DMBED_RTOS_SINGLE_THREAD' '-mcpu=cortex-m0plus' '-mthumb'
CPP     = '../gtc/arm-none-eabi-g++' '-std=c++17' '-fno-rtti' '-Wvla' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-O3' '-g1' '-DMBED_RTOS_SINGLE_THREAD' '-mcpu=cortex-m0plus' '-mthumb'
LD      = '../gtc/arm-none-eabi-gcc'
ELF2BIN = '../gtc/arm-none-eabi-objcopy'
PREPROC = '../gtc/arm-none-eabi-cpp' '-E' '-P' '-Wl,--gc-sections' '-Wl,--wrap,main' '-Wl,--wrap,_malloc_r' '-Wl,--wrap,_free_r' '-Wl,--wrap,_realloc_r' '-Wl,--wrap,_memalign_r' '-Wl,--wrap,_calloc_r' '-Wl,--wrap,exit' '-Wl,--wrap,atexit' '-Wl,-n' '--specs=nano.specs' '-mcpu=cortex-m0plus' '-mthumb'

C_FLAGS += -std=gnu99
C_FLAGS += -O3
C_FLAGS += -DTARGET_LPC11U68
C_FLAGS += -D__MBED__=1
C_FLAGS += -DDEVICE_I2CSLAVE=1
C_FLAGS += -DTARGET_LIKE_MBED
C_FLAGS += -DTARGET_NXP
C_FLAGS += -D__MBED_CMSIS_RTOS_CM
C_FLAGS += -DDEVICE_RTC=1
C_FLAGS += -DTOOLCHAIN_object
C_FLAGS += -D__CMSIS_RTOS
C_FLAGS += -DTOOLCHAIN_GCC
C_FLAGS += -DTARGET_CORTEX_M
C_FLAGS += -DTARGET_M0P
C_FLAGS += -DTARGET_UVISOR_UNSUPPORTED
C_FLAGS += -DDEVICE_SERIAL=1
C_FLAGS += -DDEVICE_INTERRUPTIN=1
C_FLAGS += -DTARGET_LPCTarget
C_FLAGS += -DTARGET_CORTEX
C_FLAGS += -DDEVICE_I2C=1
C_FLAGS += -D__CORTEX_M0PLUS
C_FLAGS += -DTARGET_FF_ARDUINO
C_FLAGS += -DTARGET_RELEASE
C_FLAGS += -DMBED_BUILD_TIMESTAMP=1526394586.66
C_FLAGS += -DARM_MATH_CM0PLUS
C_FLAGS += -DTARGET_LPC11U6X
C_FLAGS += -DDEVICE_SLEEP=1
C_FLAGS += -DTOOLCHAIN_GCC_ARM
C_FLAGS += -DDEVICE_SPI=1
C_FLAGS += -DDEVICE_ANALOGIN=1
C_FLAGS += -DDEVICE_PWMOUT=1
C_FLAGS += -DTARGET_LIKE_CORTEX_M0
C_FLAGS += -include
C_FLAGS += mbed_config.h

CXX_FLAGS += -std=c++17
CXX_FLAGS += -O3
CXX_FLAGS += -fno-rtti
CXX_FLAGS += -Wvla
CXX_FLAGS += -DTARGET_LPC11U68
CXX_FLAGS += -D__MBED__=1
CXX_FLAGS += -DDEVICE_I2CSLAVE=1
CXX_FLAGS += -DTARGET_LIKE_MBED
CXX_FLAGS += -DTARGET_NXP
CXX_FLAGS += -D__MBED_CMSIS_RTOS_CM
CXX_FLAGS += -DDEVICE_RTC=1
CXX_FLAGS += -DTOOLCHAIN_object
CXX_FLAGS += -D__CMSIS_RTOS
CXX_FLAGS += -DTOOLCHAIN_GCC
CXX_FLAGS += -DTARGET_CORTEX_M
CXX_FLAGS += -DTARGET_M0P
CXX_FLAGS += -DTARGET_UVISOR_UNSUPPORTED
CXX_FLAGS += -DDEVICE_SERIAL=1
CXX_FLAGS += -DDEVICE_INTERRUPTIN=1
CXX_FLAGS += -DTARGET_LPCTarget
CXX_FLAGS += -DTARGET_CORTEX
CXX_FLAGS += -DDEVICE_I2C=1
CXX_FLAGS += -D__CORTEX_M0PLUS
CXX_FLAGS += -DTARGET_FF_ARDUINO
CXX_FLAGS += -DTARGET_RELEASE
CXX_FLAGS += -DMBED_BUILD_TIMESTAMP=1526394586.66
CXX_FLAGS += -DARM_MATH_CM0PLUS
CXX_FLAGS += -DTARGET_LPC11U6X
CXX_FLAGS += -DDEVICE_SLEEP=1
CXX_FLAGS += -DTOOLCHAIN_GCC_ARM
CXX_FLAGS += -DDEVICE_SPI=1
CXX_FLAGS += -DDEVICE_ANALOGIN=1
CXX_FLAGS += -DDEVICE_PWMOUT=1
CXX_FLAGS += -DTARGET_LIKE_CORTEX_M0
CXX_FLAGS += -include
CXX_FLAGS += mbed_config.h

ASM_FLAGS += -x
ASM_FLAGS += assembler-with-cpp
ASM_FLAGS += -D__CMSIS_RTOS
ASM_FLAGS += -D__MBED_CMSIS_RTOS_CM
ASM_FLAGS += -D__CORTEX_M0PLUS
ASM_FLAGS += -DARM_MATH_CM0PLUS
ASM_FLAGS += -I../.
ASM_FLAGS += -I../PokittoLib
ASM_FLAGS += -I../PokittoLib/POKITTO_CORE
ASM_FLAGS += -I../PokittoLib/POKITTO_CORE/FONTS
ASM_FLAGS += -I../PokittoLib/POKITTO_CORE/PALETTES
ASM_FLAGS += -I../PokittoLib/POKITTO_HW
ASM_FLAGS += -I../PokittoLib/POKITTO_LIBS
ASM_FLAGS += -I../PokittoLib/POKITTO_LIBS/ImageFormat
ASM_FLAGS += -I../PokittoLib/POKITTO_LIBS/Synth
ASM_FLAGS += -I../PokittoLib/POKITTO_XTERNALS
ASM_FLAGS += -I../PokittoLib/POKITTO_XTERNALS/Arduino
ASM_FLAGS += -I../PokittoLib/libpff
ASM_FLAGS += -I../PokittoLib/mbed-pokitto
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/api
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/common
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/hal
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM/TARGET_LPC11U68
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/cmsis/TOOLCHAIN_GCC
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/hal
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP
ASM_FLAGS += -I../PokittoLib/mbed-pokitto/targets/hal/TARGET_NXP/TARGET_LPC11U6X

LD_FLAGS :=-Wl,--gc-sections -Wl,--wrap,main -Wl,--wrap,_memalign_r -Wl,-n --specs=nano.specs -mcpu=cortex-m0plus -mthumb 
LD_SYS_LIBS :=-Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys  -Wl,--end-group

# Tools and Flags
###############################################################################
# Rules

.PHONY: all lst size

all: firmware.bin $(PROJECT).hex size

.s.o:
	+@$(call MAKEDIR,$(dir $@))
	+@echo "Assemble: $(notdir $<)"
  
	@$(AS) -c $(ASM_FLAGS) -o $@ $<
  
.S.o:
	+@$(call MAKEDIR,$(dir $@))
	+@echo "Assemble: $(notdir $<)"
  
	@$(AS) -c $(ASM_FLAGS) -o $@ $<
 
.c.o:
	+@$(call MAKEDIR,$(dir $@))
	+@echo "Compile: $(notdir $<)"
	@$(CC) $(C_FLAGS) $(INCLUDE_PATHS) -o $@ $<

.cpp.o:
	+@$(call MAKEDIR,$(dir $@))
	+@echo "Compile: $(notdir $<)"
	@$(CPP) $(CXX_FLAGS) $(INCLUDE_PATHS) -o $@ $<

$(PROJECT).link_script.ld: $(LINKER_SCRIPT)
	@$(PREPROC) $< -o $@

$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) $(PROJECT).link_script.ld 
	+@echo "link: $(notdir $@)"
	@$(LD) $(LD_FLAGS) -T $(filter-out %.o, $^) $(LIBRARY_PATHS) --output $@ $(filter %.o, $^) $(LIBRARIES) $(LD_SYS_LIBS)

firmware.bin: $(PROJECT).elf
	$(ELF2BIN) -O binary $< $@
	+@echo "===== bin file ready to flash: $(OBJDIR)/$@ =====" 

$(PROJECT).hex: $(PROJECT).elf
	$(ELF2BIN) -O ihex $< $@

# Rules
###############################################################################
# Dependencies

DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
-include $(DEPS)
endif

# Dependencies
###############################################################################
  1. If you want to compile more files than just main.cpp (for example a library), at the top of the Makefile add your source files that need to be compiled (e.g. OBJECTS += mylibrary.o).

Now you should be set up. If you do

make

The project should compile. A folder called BUILD should be created, in which firmware.bin (and other byproducts of the compilation) will be placed, that can be loaded into Pokitto (e.g. like this) or the emulator.

Most things should work as you’re used to – you can change the compiler flags in the Makefile if you want (they’re the same as gcc flags). To force rebuild do make -B.

Emulator

Part of the workflow is running the compiled binary with the emulator. You can incorporate the emulator like this:

  1. Download and build the emulator:
cd ~/git
git clone https://github.com/felipemanga/PokittoEmu.git
cd PokittoEmu
make
  1. In your project folder create a symbolic link to the emulator binary:
    ln ~/git/PokittoEmu/BUILD/PokittoEmu ./PokittoEmu

  2. Create a script that you’ll use instead of make, for example make.sh (don’t forget to do chmod +x make.sh):

#!/bin/bash

clear; clear

make

if [ $? -eq 0 ]; then
  ./PokittoEmu ./BUILD/firmware.bin $1
fi

Now all you should do in order to compile and run the project is simply ./make.sh.

EDIT: a working, in-production Makefile (Aug. 2021)

Originally from @drummyfish , refreshed for PokittoLib changes (LibAudio etc) by Jonne
… I will also add it to the top post of this thread

Makefile (16.0 KB)

6 Likes

I created this in a bit of a hurry so that I can link it to a person who’d like to try Pokitto and they prefer the same workflow as me. Therefor there may be mistakes, but hopefully it’s better than nothing. Feel free to point out things.

2 Likes

This is actually super exciting for me, since I’d like to not have to install extra IDE tools or Text Editors (Atom) to do this. I’ll try this out when I get some extra time :smiley: Thank you so much for sharing.

1 Like

Finally had a chance to run through this quick. I used your exact main.cpp code and am getting a Segmentation fault. Not really sure how to find where this is coming from. (I’m trying to run in the emulator which I setup from your tutorial).

Most of the building went butter smooth though! I think it might be a problem with the emulator, but I’ll keep trying and see what I can figure out.

[Edit]
Just read the latest posts from the linked [WIP] Pokitto Emulator page. I too am using Fedora so it is probably the same problem for me. I guess when I get more time I’ll just have to be testing on hardware :smiley: which I don’t really have a problem with I guess. I was just looking forward to trying the Emulator out for speed’s sake.

1 Like

Try dropping -O3 for the emulator, or changing iostream to FILE API in the emulator as the other person did, these should be a temporary workarounds.

At least we now have someone who can potentially provide @FManga with more info on this bug.

@torbuntu: does switching to -O2 in the Makefile make it stop segfaulting?

Changed the Makefile flags in the PokittoEmu from -03 to -02 and there was no change. Just for testing I changed it in the game’s makefile too and it didn’t change anything from the error output.

I’m using gcc and g++ 8.2.1 (Red Hat 8.2.1-4) if that helps with anything. OS is Fedora 29 Beta.

Looking at the crash report from the segfault, it looks like the function it is dying on is called __libc_free
after
std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()

[Edit]
I’m new to cpp so it’ll take me a bit of time to get the hang of the file api to replace ifstream. That and time is a rare commodity for me :frowning: I’ll report back here after I get some time on the computer again.

1 Like

Did you get it to work? If not, can you pull the code and try again?
I switched to the C file API in loadBin.

Redid the steps from the beginning and I got the quick setup counter to run in the emulator!
Now to see what I can make :smiley: Thank you all for the steps and the software to make this a reality!

3 Likes

Just ran through this again on another computer. The instructions are great!

1 Like

I quickly wrote two pretty simple bash scripts to automate some steps.

downloadPokitto.sh used to quickly download and setup the necessary libs needed for a Pokitto project. This file assumes it is being ran in a directory called Pokitto on the Home directory.

#!/bin/bash
git clone https://github.com/pokitto/PokittoLib.git
git clone https://github.com/felipemanga/PokittoEmu.git
cd PokittoEmu
make
cd ..
wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
tar xvjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
rm gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2

new.sh for creating a new game project. The links it makes assume that the libs and emulator are downloaded into the ~/Pokitto directory created with the downloadPokitto.sh program. Another problem so far is that I couldn’t find a way to echo the Makefile into the test dir, so it is just copied from the Project directory into the new project. If someone knows how to do that then I’m all ears :]

#!/bin/bash

NEWPROJ=$1
mkdir $NEWPROJ
cd $NEWPROJ
touch mbed_config.h
touch My_settings.h

ln -s ~/Pokitto/PokittoLib/Pokitto ./PokittoLib
ln -s ~/Pokitto/gcc-arm-none-eabi-7-2018-q2-update/bin/ ./gtc
ln -s ~/Pokitto/PokittoEmu/BUILD/PokittoEmu ./PokittoEmu

echo '
#include "Pokitto.h"

Pokitto::Core pokitto;

int main()
{
	pokitto.begin(); 
	pokitto.setFrameRate(60);

	while (pokitto.isRunning())
	{
	  if (pokitto.update())
	  {
		pokitto.display.clear();
		pokitto.display.setCursor(1,1);
		pokitto.display.print("Hello Pokitto!");
	  }
	}

	return 0;
}' >> main.cpp

cp ../Makefile ./

echo '
#!/bin/bash

clear; clear

make

if [ $? -eq 0 ]; then
  ./PokittoEmu ./BUILD/firmware.bin $1
fi
' >> make.sh

chmod +x make.sh
1 Like

Is there a reason to echo file contents rather than bundling multiple files and then copying the files?

(Unrelated: you don’t actually need a pokitto object.)

The reason being I’ve never done it before :thinking: I’ll look that up because it sounds many times more elegant than what I’m doing.

Assuming you kept the script in ~/Pokitto/Scripts you could probably do something like:

cp ~/Pokitto/Scripts/main.cpp main.cpp
cp ~/Pokitto/Scripts/make.sh make.sh
chmod +x make.sh

If I were writing for Windows I wouldn’t cd into the $NEWPROJ directory,
I’d keep the script’s own directory as the local directory and then refer to the destination via $NEWPROJ
(or %NEWPROJ% as it would be if I were doing it in batch).

Then the code would be more like:

cp main.cpp $NEWPROJ/main.cpp
cp make.sh $NEWPROJ/make.sh
chmod +x $NEWPROJ/make.sh

The less assumptions you make about the location of things,
the easier it is to make a script relocatable.

1 Like

That’s a fantastic idea. I’ll rework the scripts :smiley:

1 Like

Awesome! I found the mbed_config.h can be taken out of the process, it’s only included via an option in the makefile. Also the script for flashing Pokitto is proprietary, but you can simply use dd (see PokittoLibre).

For small tasks such as setting up a new project I don’t even use scripts – I have a one line command somewhere in my terminal history that copies the symbolic links and files into the current dir. I simply grep that line out of the history and execute :smile:

1 Like

I now have a Scripts directory inside my ~/Pokitto directory and inside there is where I put the Makefile, main.cpp, new.sh and make.sh

new.sh changed a bit to this:

#!/bin/bash

NEWPROJ=$1
mkdir $NEWPROJ

touch $NEWPROJ/My_settings.h
touch $NEWPROJ/mbed_config.h

ln -s ~/Pokitto/PokittoLib/Pokitto $NEWPROJ/PokittoLib
ln -s ~/Pokitto/gcc-arm-none-eabi-7-2018-q2-update/bin/ $NEWPROJ/gtc
ln -s ~/Pokitto/PokittoEmu/BUILD/PokittoEmu $NEWPROJ/PokittoEmu

cp ~/Pokitto/Scripts/main.cpp $NEWPROJ/main.cpp

cp ~/Pokitto/Scripts/Makefile $NEWPROJ/Makefile

cp ~/Pokitto/Scripts/make.sh $NEWPROJ/make.sh
chmod +x $NEWPROJ/make.sh

So now I just have to run new.sh with a path and name of the project as an argument: ./new.sh ~/PokittoProjects/NewProjectHere and it will set everything up for me :] Then when I go in there I just run ./make.sh and it will pop up in the emulator after compiling as normal.

I’d like to see your simple setup @drummyfish!

I am going to be trying to streamline my NetBeans setup to be a bit more efficient, but with the testing I was doing it’ll be so much easier with this script now, since I use this to generate half the project before I go through NetBeans setup wizard for starting a C++ project with sources.

2 Likes

@drummyfish is this still a viable option? had some issues over the weekend, not sure if gcc-related or something else.

2 Likes

It should still be a viable option, as I’m still using a Makefile derived from this one. However, it is out of date as @drummyfish notes at the start of the first post:

NOTE: This is a little older now and the Makefile may have problems with the new PokittoLib version. These can usually be easily fixed, just expect you may encounter some issues.

Drummyfish might be able to provide an updated Makefile, but if not, I might be able to pull an updated one together from my projects. However, to make sure you’re not encountering other problems, what are the errors you’re getting?

I’ll take another stab @ it tomorrow. I was pretty tired when walking through things. I don’t even remember the error I was getting.