git clone https://github.com/crosstool-ng/crosstool-ng.git
cd crosstool-ng
./bootstrap
./configure --prefix=$HOME/install/crosstool-ng
make install
echo 'export PATH="${PATH}:$HOME/install/crosstool-ng/bin"' >>~/install/crosstool-ng/crosstool-ng.env
. ./install/crosstool-ng/crosstool-ng.env
mkdir -p ~/workdir
cd ~/workdir
ct-ng list-samples
ct-ng i686-ubuntu16.04-linux-gnu
ct-ng menuconfig
nice -19 ct-ng build.4
ls ~/x-tools/i686-xg-linux-gnu/
In a old post I wrote where to get and how to use a gcc cross toolchain to compile from a pc host to a raspberry target.
Here how to use distcc
on target raspberry (and distccd
on pc host) to build faster over a distributed network (a cross toolchain installed on network nodes is a prerequisite).
Assuming the pc have ip address 192.168.1.210
and pi 192.168.1.2
, on the host:
pc host $ cd $HOME/toolchains/raspberry-pi
pc host $ export PATH=$PWD/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/libexec/gcc/arm-linux-gnueabihf/4.8.3:$PATH
pc host $ export PATH=$PWD/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/bin:$PATH
pc host $ distccd --daemon --jobs 8 --allow 192.168.1.2 --verbose --log-stderr --no-detach
Using --no-detach
the process will sleep listening for connections and eventually log on stdout, on pi:
pi target $ export DISTCC_HOSTS="192.168.1.210"
pi target $ CC="distcc gcc" CXX="distcc g++" cmake -DCMAKE_BUILD_TYPE=release
pi target $ make -j4
DISTCC_HOSTS
support more machines (see distcc documentation for more options) Here I’m using --jobs 8
on distccd side and only -j4
on distcc side. The drawbacks are that not all packages support CC
and CXX
variables from env correctly, as not every package support a parallel build.
An alternative to pass CC CXX
is to use the environment PATH
variable (export PATH=/usr/lib/ccache:/usr/lib/distcc:$PATH
) to specify a directory which should contain symlinks (eg: gcc -> ../../bin/ccache
or clang++-4.0 -> ../../distcc
), the name of the symlink should match the invoked compiler and point to the real executables of ccache and distcc.
download tools-master.zip
cd /tmp
# I'm using i686 the directory depend on host architecture (32/64 bit)
unzip ~/Downloads/tools-master.zip "tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/*"
mv tools-master/arm-bcm2708 ~/toolchains/raspberry-pi/
export PATH=$HOME/toolchains/raspberry-pi/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH
test.cpp:
#include <iostream>
int main(int argc, char **argv)
{
std::cout << "hello world" << std::endl;
return 0;
}
run test on rpi:
arm-linux-gnueabihf-g++ -Wall -O2 -o test test.cpp
scp test pi@rpi-host:/tmp
ssh pi@rpi-host
/tmp/test
$ hello world
I like make
, it allow to automate complex tasks with not much code, and it make handling dependencies very easy.
For a simple test based on few packages I wrote this define
:
define configure-rule
$(1)_install = $(DESTDIR)/$(1)-install-my-stamp
$(1)_builddir = $$($(1)_dir)/build
$(DESTDIR)/$(1)-install-my-stamp: $$($(1)_deps)
ifneq ($$($(1)_pre_config),)
$$($(1)_pre_config)
endif
mkdir -p $$($(1)_builddir)
cd $$($(1)_builddir) && \
$$($(1)_env) ../configure --cache-file=$(SRCDIR)/$(1)-config.cache \
$$($(1)_configure)
$(NICE) make -C $$($(1)_builddir) $$($(1)_make_target) $(PARALLEL)
ifneq ($$($(1)_post_make),)
$$($(1)_post_make)
endif
touch $$@
.PHONY: build-$(1) clean-$(1)
build-$(1): $$($(1)_install)
clean-$(1):
-rm -fr $$($(1)_builddir) $$($(1)_install) $(SRCDIR)/$(1)-config.cache
endef
Then use few variables for each packet:
mpc_dir = src/mpc-0.8.1
mpc_env = CONFIG_SITE=$(SRCDIR)/config.site
mpc_configure = --prefix=$(DESTDIR) \
--disable-shared --enable-static \
--with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR)
mpc_deps = $(untar_dep) $(gmp_install) $(mpfr_install)
mpc_make_target = install
$(eval $(call configure-rule,mpc))
The complete Makefile.gz, it build gcc-4.7.2
but has been used for test purpose only, don’t use it as reference for building gcc.
One feature not so known about gcc are specs
files
gcc -dumpspecs >spec
output the built-in specs file
If we need to add some option, compile/link flag to be used always or on some condition we can add it to the dumped spec file, example:
*link:
-rpath /opt/someroot/lib
add always the rpath to the link options, we can try the spec file with the command line:
gcc -specs=spec test.c
readelf -d a.out |grep RPATH
on startup gcc/g++ look for a spec file on the filesystem, we can guess the full path with strace
and grep
:
strace -fF -o /tmp/g++.log g++ test.cpp
grep specs /tmp/g++.log
if we build our toolchain we can add a configure option --with-specs=
, the argument is a spec code, it isn’t shown on -dumpspecs
but will be used, example:
--with-specs="%{shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}%{!shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}"
ADB=$(HOME)/dev/a/android/adt-bundle-linux-x86-20130729/sdk/platform-tools/adb
AND_PREBUILT=$(HOME)/dev/a/android/src/prebuilt
AND_PLATFORM=android-8
CC=$(AND_PREBUILT)/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-gcc
#CC=$(AND_PREBUILT)/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc
#CC=$(AND_PREBUILT)/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-gcc
#CC=$(AND_PREBUILT)/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcc
CFLAGS += -Wall -O0 -fno-stack-protector
CFLAGS += -mno-thumb
CFLAGS += --sysroot=$(AND_PREBUILT)/ndk/android-ndk-r5/platforms/$(AND_PLATFORM)/arch-arm
CFLAGS += -I$(HOME)/dev/a/android/src/system/core/include
#LDFLAGS += -nostdlib -lc -ldl
#LIBS += $(AND_PREBUILT)/ndk/android-ndk-r5/platforms/$(AND_PLATFORM)/arch-arm/usr/lib/crtbegin_dynamic.o
zergrush_LDFLAGS += -L.
zergrush_LIBS += -ldiskconfig -lcutils
all: zergrush
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
libcutils.so libdiskconfig.so:
$(ADB) pull /system/lib/$@
zergrush: zergRush.o libcutils.so libdiskconfig.so
$(CC) $(CFLAGS) -o $@ $^ $(zergrush_LDFLAGS) $(zergrush_LIBS)
.PHONY: install
install: zergrush
$(ADB) push zergrush /data/local/tmp/zergrush
$(ADB) shell chmod 0755 /data/local/tmp/$(TARGET)
.PHONY: clean
clean: $(wildcard zergrush *.o)
-[ "$<" = "" ] || rm -fr $<
.PHONY: adb
adb:
@echo $(ADB)
Debianizzando ts – task spooler che già utilizza di suo dei cflags molto rigidi
-pedantic -ansi -Wall -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__
mi sono accorto che Debian ne usa ancora di più verbosi e le informazion che generano possono essere interessanti
-D_FORTIFY_SOURCE=2 -fstack-protector-strong -Wformat -Werror=format-security