11---
2- title : Using Brickstrap to Cross-Compile
3- subject : Cross-Compiling
2+ title : " Using Brickstrap to Cross-Compile"
3+ subject : " Cross-Compiling"
4+ author : " @dlech"
45---
56
67* Table of Contents
@@ -85,7 +86,7 @@ command tells brickstrap to build a file system but to not actually create an
8586image file. This will take 20 to 30 minutes or longer depending on the speed of
8687your machine and Internet connection.
8788
88- brickstrap -b ev3-ev3dev-jessie -d ev3-dev-env create-rootfs
89+ brickstrap -b ev3-ev3dev-jessie -d ev3-rootfs create-rootfs
8990
9091## Working in the Brickstrap Shell
9192
@@ -94,7 +95,7 @@ shell inside of the directory that was created. This is almost like working in
9495a virtual machine except that qemu is used to run individual commands instead
9596of the whole thing being run inside of a virtual environment.
9697
97- brickstrap -b ev3-ev3dev-jessie -d ev3-dev-env shell
98+ brickstrap -b ev3-ev3dev-jessie -d ev3-rootfs shell
9899
99100Now, you can install packages and run programs almost just as if you were on the
100101actual EV3. Don't forget to run ` apt-get update ` first! For starters, you will
@@ -215,3 +216,172 @@ on each line that starts with `(gdb)`.
215216Since gdb is running in an emulated environment using qemu, you will
216217occasionally see errors like the unsupported syscall above. Most errors don't
217218seem to cause any problems, but it may limit the use of some features of gdb.
219+
220+ ## Using a "Real" Cross-Compiler
221+
222+ If you are compiling a larger project, you will quickly notice that while the
223+ methods above are faster than compiling on the EV3 itself, they are still slow
224+ compared to compiling on your host computer. This is because inside of the
225+ brickstrap shell, it is actually running ARM machine code using an emulator
226+ instead of running a native binary.
227+
228+ So, we can actually use a "real" cross-compiling toolchain to compile much
229+ faster but still use the root file system created by brickstrap as the source
230+ of header files and libraries.
231+
232+ I haven't done this yet with a regular makefile, but I'll use [ brickman]
233+ as an example, which uses CMake for the build system.
234+
235+ [ brickman ] : https://github.com/ev3dev/brickman
236+
237+ ### Example using Vala and CMake
238+
239+ First, we will assume that you ran brickstrap as described above to create a
240+ root file system on your host computer at ` /home/user/work/ev3-rootfs ` .
241+ While we are talking about the root files system, let's get is setup. Do this
242+ in the brickstrap shell (see above if you don't remember how to start the
243+ brickstrap shell).
244+
245+ nano /etc/apt/sources.list
246+
247+ We need to edit source package repositories. Edit the file so that it looks like
248+ this...
249+
250+ deb http://cdn.debian.net/debian jessie main contrib non-free
251+ deb-src http://cdn.debian.net/debian jessie main contrib non-free
252+
253+ deb http://ev3dev.org/debian jessie main
254+ deb-src http://ev3dev.test/debian jessie main
255+
256+ Save the changes, then run...
257+
258+ apt-get update
259+ apt-get build-dep brickman
260+ apt-get install symlinks
261+
262+ This will install all of the package that are needed when building brickman.
263+ Now, for a very important part. Some libraries use absoloute symlinks, which is
264+ bad for us when we are cross compiling because we are accessing files in the
265+ root file system created by brickstrap from outside of the brickstrap shell.
266+ This is why we installed the ` symlinks ` package. Simply run...
267+
268+ symlinks -c /usr/lib/arm-linux-gnueabi
269+
270+ This will change any absolute links to relative links and save us a bunch of
271+ trouble later. This should be all that we need to do inside of the brickstrap
272+ shell.
273+
274+ You will also need to install a cross compiler toolchain and and some other build
275+ tools on your host computer (not in brickstrap shell)...
276+
277+ sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi cmake valac pkg-config
278+
279+ {% include icon.html type="warning" %}
280+ These cross-compiler packages are only available on Ubuntu. Sorry Debian users.
281+ {:.alert .alert-warning}
282+
283+ And we need to download the brickman source code...
284+
285+ cd ~/work
286+ git clone https://github.com/ev3dev/brickman.git
287+
288+ The source code will be downloaded to ` /home/user/work/brickman ` , but don't
289+ switch to that directory. We are going to build "out of tree" (that means in
290+ another directory that is not the source code directory). Let's make that
291+ directory now - and a couple more files too.
292+
293+ mkdir build-area
294+ touch arm-linux-gnueabi.cmake
295+ touch ev3-rootfs-cross.env
296+
297+ Use your favorite text editor to edit the two empty files we just created with
298+ ` touch ` . First, ` arm-linux-gnueabi.cmake ` should look like this...
299+
300+ set(SYSROOT_PATH /home/user/work/ev3-rootfs)
301+
302+ set(CMAKE_SYSTEM_NAME Linux)
303+
304+ set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc)
305+ set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)
306+
307+ set(CMAKE_FIND_ROOT_PATH ${SYSROOT_PATH})
308+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
309+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
310+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
311+
312+ This will tell CMake to use programs on our host computer (which is why we had
313+ to install ` valac ` and ` pkg-config ` on the host computer). But, it will look
314+ for header files and libraries inside of the root file system we created with
315+ brickstrap. And, of course, it tells us to use the cross-compiler too.
316+
317+ The ` ev3-rootfs-cross.env ` file needs to look like this...
318+
319+ SYSROOT_PATH=/home/user/work/ev3-rootfs
320+
321+ export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
322+ export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
323+ export PKG_CONFIG_SYSROOT_DIR=${SYSROOT_PATH}
324+ export PKG_CONFIG_LIBDIR=${SYSROOT_PATH}/usr/lib/arm-linux-gnueabi/pkgconfig
325+ export PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR}:${SYSROOT_PATH}/usr/lib/pkgconfig
326+ export PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR}:${SYSROOT_PATH}/usr/share/pkgconfig
327+ export PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR}:${SYSROOT_PATH}/usr/local/lib/arm-linux-gnueabi/pkgconfig
328+ export PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR}:${SYSROOT_PATH}/usr/local/lib/pkgconfig
329+ export PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR}:${SYSROOT_PATH}/usr/local/share/pkgconfig
330+
331+ export XDG_DATA_DIRS=${SYSROOT_PATH}/usr/local/share:${SYSROOT_PATH}/usr/share
332+
333+ These set environment variables so that pkg-config and vala will search for
334+ files inside of our root file system instead of the usual places on the host
335+ computer. To make these actually take effect, run...
336+
337+ source ev3-rootfs-cross.env
338+
339+ Now, lets actually try to build something...
340+
341+ cd build-area
342+ cmake ../brickman -DCMAKE_TOOLCHAIN_FILE=../arm-linux-gnueabi.cmake
343+ make
344+
345+ If all went well, you should end up with a ` brickman ` binary that you can
346+ copy to your EV3 and run.
347+
348+ ### Example using Makefiles
349+
350+ I haven't actually done this yet, so feel free to edit this page and add more
351+ info. The basic gist is that you need to have something like this...
352+
353+ PROGRAM = my-program
354+ CROSS_COMPILE = arm-linux-gnueabi-
355+ SYSROOT = /home/user/work/ev3-rootfs
356+
357+ CC=$(CROSS_COMPILE)gcc
358+ LD=$(CROSS_COMPILE)ld
359+ CFLAGS= --sysroot=$(SYSROOT) -g -I$(SYSROOT)/usr/include
360+
361+ all: $(PROGRAM)
362+
363+ LIBDIR = -L=/usr/lib/arm-linux-gnueabi
364+ #LIBDIR = -L$(SYSROOT)/usr/lib/arm-linux-gnueabi
365+
366+ LIBS = -lpthread
367+
368+ LDFLAGS= $(LIBDIR) $(LIBS)
369+ SOURCE = my_program.c
370+
371+ OBJS = $(SOURCE:.c=.o)
372+
373+ $(PROGRAM): $(OBJS)
374+ $(CC) -o $@ $(OBJS) $(LDFLAGS)
375+
376+ clean:
377+ -rm -f $(OBJS) $(PROGRAM)
378+
379+ The important points are that you:
380+
381+ * Use ` arm-linux-gnueabi-gcc ` for the compiler and ` arm-linux-gnueabi-ld ` for
382+ the linker.
383+ * Pass the ` --sysroot=$(SYSROOT) ` option to the compiler and point it to the
384+ root file system created by brickstrap.
385+ * The ` = ` in ` -L= ` means search for libraries relative to ` $(SYSROOT) ` . You could
386+ optionally specify the full path.
387+ * The path to include files need to include ` $(SYSROOT) ` as well.
0 commit comments