Upto: Table of Contents of full book "Programming the Raspberry Pi GPU"

Compiling programs for the Raspberry Pi

Resources

Generic info

Versions of gcc

As of the end of 2015, the raspbian distros give gcc 4.6 as the default C compiler. This is a bit old and you will probably want to update it to version 4.8:

	
  sudo apt-get install gcc-4.8
	
      

The default C compiler will still be version 4.6. The new version is in /usr/bin/gcc-4.8. You can use it by, say

	
/usr/bin/gcc-4.8 ...
	
      

In a Makefile you can set it as the compiler by

	
CC = /usr/bin/gcc-4.8
	
      

To make it the default compiler, the best way seems to be to use the update-alternatives command

	
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 80
	
      

This make version 4.8 the default, but you can toggle back to 4.6 if desired. See How to install and use GCC g++ v4.7 and C++11 on Ubuntu 12.04 (beta) for further details.

Gcc compile flags

The command

	
gcc -mcpu=native -march=native -Q --help=target
	
      

prints lots of interesting stuff on what gcc figures out. On the RPi2 with gcc-4.8 it gives

	
The following options are target specific:
  -mabi=                      		aapcs-linux
  -mabort-on-noreturn         		[disabled]
  -mandroid                   		[disabled]
  -mapcs                      		[disabled]
  -mapcs-float                		[disabled]
  -mapcs-frame                		[disabled]
  -mapcs-reentrant            		[disabled]
  -mapcs-stack-check          		[disabled]
  -march=                     		armv7-a
  -marm                       		[enabled]
  -mbig-endian                		[disabled]
  -mbionic                    		[disabled]
  -mcallee-super-interworking 		[disabled]
  -mcaller-super-interworking 		[disabled]
  -mcpu=                      		cortex-a7
  -mfix-cortex-m3-ldrd        		[enabled]
  -mfloat-abi=                		hard
  -mfp16-format=              		none
  -mfpu=                      		vfp
  -mglibc                     		[enabled]
  -mhard-float                		
  -mlittle-endian             		[enabled]
  -mlong-calls                		[disabled]
  -mpic-register=             		
  -mpoke-function-name        		[disabled]
  -msched-prolog              		[enabled]
  -msingle-pic-base           		[disabled]
  -msoft-float                		
  -mstructure-size-boundary=  		0x20
  -mthumb                     		[disabled]
  -mthumb-interwork           		[enabled]
  -mtls-dialect=              		gnu
  -mtp=                       		auto
  -mtpcs-frame                		[disabled]
  -mtpcs-leaf-frame           		[disabled]
  -mtune=                     		[default]
  -muclibc                    		[disabled]
  -munaligned-access          		[enabled]
  -mvectorize-with-neon-double 		[disabled]
  -mvectorize-with-neon-quad  		[enabled]
  -mword-relocations          		[disabled]
  -mwords-little-endian       		[disabled]

  Known ARM ABIs (for use with the -mabi= option):
    aapcs aapcs-linux apcs-gnu atpcs iwmmxt

  Known ARM architectures (for use with the -march= option):
    armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5e armv5t armv5te armv6
    armv6-m armv6j armv6k armv6s-m armv6t2 armv6z armv6zk armv7 armv7-a armv7-m
    armv7-r armv7e-m armv8-a iwmmxt iwmmxt2 native

  Known __fp16 formats (for use with the -mfp16-format= option):
    alternative ieee none

  Known ARM FPUs (for use with the -mfpu= option):
    crypto-neon-fp-armv8 fp-armv8 fpv4-sp-d16 neon neon-fp-armv8 neon-fp16
    neon-vfpv4 vfp vfp3 vfpv3 vfpv3-d16 vfpv3-d16-fp16 vfpv3-fp16 vfpv3xd
    vfpv3xd-fp16 vfpv4 vfpv4-d16

  Valid arguments to -mtp=:
    auto cp15 soft

  Known floating-point ABIs (for use with the -mfloat-abi= option):
    hard soft softfp

  Known ARM CPUs (for use with the -mcpu= and -mtune= options):
    arm1020e arm1020t arm1022e arm1026ej-s arm10e arm10tdmi arm1136j-s
    arm1136jf-s arm1156t2-s arm1156t2f-s arm1176jz-s arm1176jzf-s arm2 arm250
    arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm70 arm700 arm700i arm710
    arm7100 arm710c arm710t arm720 arm720t arm740t arm7500 arm7500fe arm7d
    arm7di arm7dm arm7dmi arm7m arm7tdmi arm7tdmi-s arm8 arm810 arm9 arm920
    arm920t arm922t arm926ej-s arm940t arm946e-s arm966e-s arm968e-s arm9e
    arm9tdmi cortex-a15 cortex-a5 cortex-a7 cortex-a8 cortex-a9 cortex-m0
    cortex-m0plus cortex-m1 cortex-m3 cortex-m4 cortex-r4 cortex-r4f cortex-r5
    ep9312 fa526 fa606te fa626 fa626te fa726te fmp626 generic-armv7-a iwmmxt
    iwmmxt2 marvell-pj4 mpcore mpcorenovfp native strongarm strongarm110
    strongarm1100 strongarm1110 xscale

  TLS dialect to use:
    gnu gnu2
	
      

If you want to find out what they all mean, look at GCC Option Summary

I have built up an impressive set of options, basically by chucking in everything I saw. They are now

	
 -mfloat-abi=hard -mcpu=arm1176jzf-s -fomit-frame-pointer -mabi=aapcs-linux -mtune=arm1176jzf-s -mfpu=vfp -Wno-psabi -mno-apcs-stack-check -mstructure-size-boundary=32 -mno-sched-prolog -march=armv6zk
	
      

Some of these are specific to the RPi version 1, some are redundant, etc. These are discussed below.

In summary, this looks reasonable:

	
-mabi=aapcs-linux -mtune=cortex-a7 -march=armv7-a -mfpu=vfp -mstructure-size-boundary=32 -mno-sched-prolog
	
      

This looks okay for some optimisation while still allowing debugging.

Includes

Dispmanx

The Dispmanx include files are not organised very nicely. Ideally, only the toplevel directory /opt/vc/include should be needed. Unfortunately this includes files which don't have base relative to this file. The following set may be needed:

	
DMX_INC =  -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
INCLUDES = $(DMX_INC)
	
      

EGL

This adds no new directories:

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
INCLUDES = $(DMX_INC) $(EGL_INC)
	
      

OpenMAX

I use both the OpenMAX API and the wrapper from Broadcom, the IL Client library. The IL Client library is intended for wider use than just the RPi, and so contains some conditional execution flags. The main one is to choose between 32- and 64-bit architectures, since time to OpenMAX is 64 bits, and on a 32-bit machine that needs to be managed in a struct, not a simple type. This flag is OMX_SKIP64BIT.

I also use the define RASPBERRY_PI in my code where appropriate. There doesn't seem to be a default RPI define flag.

Appropriate includes and cflags are:

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
OMX_INC =  -I /opt/vc/include/IL
OMX_ILCLIENT_INC = -I/opt/vc/src/hello_pi/libs/ilclient

INCLUDES = $(DMX_INC) $(EGL_INC) $(OMX_INC) $(OMX_ILCLIENT_INC)
CFLAGS =  -DOMX_SKIP64BIT -DRASPBERRY_PI $(INCLUDES)
	
      

OpenGL ES

I am using the esUtils from the OpenGL ES book by Munshi et al, and their files are in a subdirectory Common of my code. The includes reflect this

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
GLES_INC = -ICommon/
INCLUDES = $(DMX_INC) $(EGL_INC) $(GLES_INC)
	
      

OpenVG

There are no additional include directories

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
OPENVG_INC = 
INCLUDES = $(DMX_INC) $(EGL_INC) $(OPENVG_INC)
	
      

Libraries

Dispmanx

The libraries required are just

	
DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
LDFLAGS = $(DMX_LIBS)
	
      

EGL

The EGL libraries unfortunately pull in the GL ES libraries as well as the expected Dispmanx and EGL libraries:

	
DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
LDFLAGS = $(DMX_LIBS) $(EGL_LIBS)
	
      

OpenMAX

The libraries are both the standard OpenMAX libraries and the IL Client libraries:

	
DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
OMX_LIBS = -lopenmaxil 
OMX_ILCLIENT_LIBS = -L/opt/vc/src/hello_pi/libs/ilclient -lilclient

LDFLAGS = $(DMX_LIBS) $(EGL_LIBS) $(OMX_LIBS) $(OMX_ILCLIENT_LIBS)
	
      

OpenGL ES

In addition to the Munshi objects, the maths library has to be added. The EGL_LIBS already has the GLESv2 library:

	
DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
LDFLAGS = $(DMX_LIBS) $(EGL_LIBS) \
	Common/esUtil.o Common/esShader.o Common/esTransform.o\
	-lm
	
      

OpenVG

There is just an additional OpneVG library

	
DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
OPENVG_LIBS = -lOpenVG
	
      

Sample Makefiles

Dispmanx

This Makefile is for the directory OpenMAX/Components with C file info.c. The pre-processor flags are for the RPi2

	
DMX_INC =  -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux

INCLUDES = $(DMX_INC)

CFLAGS = $(INCLUDES)
CPPFLAGS = -march=armv7-a -mtune=cortex-a7

DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
LDFLAGS =  $(DMX_LIBS)

all: info
	
      

Running the command make will build all executables.

EGL

This Makefile is for the directory OpenMAX/Components with C files info.c, context and window.c. The pre-processor flags are for the RPi2.

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
INCLUDES = $(DMX_INC) $(EGL_INC)

CFLAGS = $(INCLUDES)
CPPFLAGS = -march=armv7-a -mtune=cortex-a7

DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib -lEGL -lGLESv2 

LDFLAGS = $(DMX_LIBS) $(EGL_LIBS)

all: context info window
	
      

Running the command make will build all executables.

OpenMAX

This Makefile is for the directory OpenMAX/Components with C files info.c, listcomponents.c and portinfo.c. The pre-processor flags are for the RPi2

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
OMX_INC =  -I /opt/vc/include/IL
OMX_ILCLIENT_INC = -I/opt/vc/src/hello_pi/libs/ilclient
INCLUDES = $(DMX_INC) $(EGL_INC) $(OMX_INC) $(OMX_ILCLIENT_INC)

CFLAGS=-g -DRASPBERRY_PI -DOMX_SKIP64BIT $(INCLUDES)
CPPFLAGS = -march=armv7-a -mtune=cortex-a7

DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
OMX_LIBS = -lopenmaxil 
OMX_ILCLIENT_LIBS = -L/opt/vc/src/hello_pi/libs/ilclient -lilclient

LDFLAGS =  $(DMX_LIBS) $(EGL_LIBS) $(OMX_LIBS) $(OMX_ILCLIENT_LIBS)

all: info listcomponents portinfo
	
      

Running the command make will build all executables.

OpenVG

This Makefile is for the directory OpenVG with a C file simple_shape.c and ellipse.c. The pre-processor flags are for the RPi2

	
DMX_INC =  -I/opt/vc/include/ -I /opt/vc/include/interface/vmcs_host/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
EGL_INC = 
OPENVG_INC =
INCLUDES = $(DMX_INC) $(EGL_INC) $(OPENVG_INC)

CFLAGS= $(INCLUDES)
CPPFLAGS = -march=armv7-a -mtune=cortex-a7

DMX_LIBS =  -L/opt/vc/lib/ -lbcm_host -lvcos -lvchiq_arm -lpthread
EGL_LIBS = -L/opt/vc/lib/ -lEGL -lGLESv2 
OPENVG_LIBS = -lOpenVG

LDFLAGS =  $(DMX_LIBS) $(EGL_LIBS) $(OPENVG_LIBS)

all: simple_shape ellipse
	
      

Conclusion

This chapter is perhaps premature, but gives a summary of building programs for the RPi.


Copyright © Jan Newmarch, jan@newmarch.name
Creative Commons License
" Programming AudioVideo on the Raspberry Pi GPU " by Jan Newmarch is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License .
Based on a work at https://jan.newmarch.name/RPi/ .

If you like this book, please contribute using PayPal

Or Flattr me:
Flattr this book