Compiling raspistill

Raspberry Flavoured Goodness

I am working on a problem where I need to capture images with a camera and put them on a large screen.  The raspberry pi with its optional camera board, and a large screen TV are the perfect elements to solve this problem.  The program raspistill will take an image and put it on the screen for you which solves most of my problem.  Thankfully the raspistill is open source software and so my attack plan was to examine that code then modify it to my needs.

Initial compile

Getting your hands on the source code for raspistill is easy

git clone https://github.com/raspberrypi/userland.git

Then I mostly used the instructions from http://thinkrpi.wordpress.com/2013/05/22/opencvpi-cam-step-2-compilation/

  • cd userland
  • sed -i ‘s/if (DEFINED CMAKE_TOOLCHAIN_FILE)/if (NOT DEFINED CMAKE_TOOLCHAIN_FILE)/g’ makefiles/cmake/arm-linux.cmake
  • cmake -DCMAKE_BUILD_TYPE=Release
  • make

<Patience> <More patience> All compiles! If only most software was this well behaved.

Speed Bumps

Since my final goal is to make an executable like raspistillyuv, why not use raspistillyuv as a proxy to let me sort out the build environment. Using find for a while located the source code at userland/host_applications/linux/apps/raspicam/RaspiStillYUV.c.  So I created a new directory /home/pi/raspicam  and copied RaspiStillYUV.c to it. A bit of include chasing also showed that I needed to copy

RaspiCamControl.c RaspiCLI.h RaspiPreview.h RaspiCamControl.h RaspiCLI.c RaspiPreview.c

The simple plan was to compile and link the c files.  On the Raspberry Pi its well known that you have to include some extra paths in order to make progress. So my first guess at a compile command was[1]

g++ -I . -std=gnu++0x -isystem /opt/vc/include/ -isystem /opt/vc/include/interface/vcos/pthreads/ -isystem /opt/vc/include/interface/vmcs_host/linux/ RaspiStillYUV.c

and we promptly hit the following error

RaspiStillYUV.c:62:33: fatal error: interface/mmal/mmal.h: No such file or directory

Hunt for the missing headers

Now all the raspberry pi specific code is usually found under /opt/vc/include.  Searching under here shows that there is no mmal.h installed. I did find /opt/vc/lib/libmmal.so.  So how did this get onto the system? dpkg can do the reverse lookup for us

$ dpkg -S /opt/vc/lib/libmmal.so
libraspberrypi0: /opt/vc/lib/libmmal.so

This would normally mean that the associated headers would be included in libraspberrypi0-dev which doesn’t exist.  libraspberrypi-dev does exist but

$ dpkg -L libraspberrypi-dev |grep mmal

gives nothing. libraspberrypi-dev (1.20140618-1) now does contain these headers. Be careful of what you trust in the original blog entry (this update was written on 20140627) Also

$ apt-file search mmal.h

gives nothing.

However, since the userland repository compiled up the camera binaries it must contain all the mmal code.  And a find turns up

userland/interface/mmal/mmal.h

mmal-dev

It would appear that the mmal headers would naturally go under the /opt/vc/include/interface directory. A tempting solution is to just copy the headers into the directory and declare the job done, however having been down that path I know it is the darkside (been free of the darkside since 2002) and always ends in tears/reinstall of OS.   The correct solution is to make a package.

The fastest way I could think of to create a deb package is

$mkdir mmal-dev-20130909 && cd mmal-dev-20130909
$cp -r ~/userland/interface/mmal .
$cat >Makefile <<EOF
install:
	cp -r mmal /opt/vc/include/interface/

uninstall:
	rm -rf /opt/vc/include/interface/mmal
EOF
$sudo checkinstall

Back to the problem of compiling RaspiStillYUV.c

Rather than writing Makefiles, I use a program called cake that writes the Makefile and then calls make. The CFLAGS that cake uses on the raspberry pi are

-I . -fPIC -g -Wall -march=armv6 -mfpu=vfp -mfloat-abi=hard -isystem /opt/vc/include/ -isystem /opt/vc/include/interface/vcos/pthreads/ -isystem /opt/vc/include/interface/vmcs_host/linux/

which leads to the link error

undefined reference to `mmal_component_create'

Which means that we also need to specify the following link flags

-Wall -Werror -march=armv6 -mfpu=vfp -mfloat-abi=hard -L /opt/vc/lib -lbcm_host -lmmal

And then all is well.

Footnotes

1. Ha! On a proof read I discovered that I’ve outed myself as a C++ programmer not a C programmer. 🙂 Back to Post

Advertisements
Tagged with: , ,
Posted in Uncategorized
5 comments on “Compiling raspistill
  1. Joe Malek says:

    Hi: I am planning on following your instructions above to compile raspistill as a start to building a video application. I am also somewhat a beginner at Linux, stumbling my way through things eventually. My Raspberry is the new 2 B. Any new words of wisdom come up since this article was written on September of 2013?

    Thanks for any help.

    Joe Malek

    • Hi Joe,

      I gave RaspiStillYUV.c a compile. So as at 2 March 2015, simply copy

      RaspiStillYUV.c
      RaspiPreview.h
      RaspiPreview.c
      RaspiCamControl.h
      RaspiCamControl.c
      RaspiCLI.h
      RaspiCLI.c

      into your own test directory. Any other headers you need like mmal.h are included by installing the package libraspberrypi-dev.

      Then I compiled with

      cake RaspiStillYUV.c –append-LINKFLAGS=”-L/opt/vc/lib -lbcm_host -lmmal -lvcos -lpthread -lmmal_core -lmmal_util”

      Let me know of any difficulties.

      Best wishes,
      Geoff

  2. Hi Joe,

    Feel free to contact me with any problems you encounter. I’m going to go and follow the instructions myself to see what does/doesn’t work. The only tip I can think of: I use a program called “cake” to make compiling easier. https://github.com/Zomojo/Cake

    Cheers,
    Geoff

  3. chrisspen says:

    Your sed command is malformed:

    bash: syntax error near unexpected token `(‘

    • Hi,

      These instructions are two years out of date now. 🙂 Did you happen to see the earlier comment (2 March 2015) about simply copying the relevant files and using a program called “cake” to do the build?

      What is your goal? For example, are you trying to only build raspistill? Or the entire userland?

      Best wishes,
      Geoff

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: