diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..270022c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dockcross diff --git a/Dockerfile b/Dockerfile index 58d11fc..f33ff31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,40 +17,44 @@ RUN apt-get update && apt-get -y install \ make \ ncurses-dev \ pkg-config \ + libtool \ python \ rsync \ sed \ + bison \ + flex \ tar \ vim \ wget \ + runit \ xz-utils && \ apt-get -y clean # Build and install CMake from source. WORKDIR /usr/src RUN git clone git://cmake.org/cmake.git CMake && \ - cd CMake && \ - git checkout v3.4.3 && \ - cd .. && mkdir CMake-build && cd CMake-build && \ - /usr/src/CMake/bootstrap \ - --parallel=$(nproc) \ - --prefix=/usr && \ - make -j$(nproc) && \ - ./bin/cmake -DCMAKE_USE_SYSTEM_CURL:BOOL=ON \ - -DCMAKE_BUILD_TYPE:STRING=Release \ - -DCMAKE_USE_OPENSSL:BOOL=ON . && \ - make install && \ - cd .. && \ - rm -rf CMake* - + cd CMake && \ + git checkout v3.4.3 && \ + cd .. && mkdir CMake-build && cd CMake-build && \ + /usr/src/CMake/bootstrap \ + --parallel=$(nproc) \ + --prefix=/usr && \ + make -j$(nproc) && \ + ./bin/cmake -DCMAKE_USE_SYSTEM_CURL:BOOL=ON \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DCMAKE_USE_OPENSSL:BOOL=ON . && \ + make install && \ + cd .. && \ + rm -rf CMake* + # Build and install Ninja from source RUN git clone https://github.com/martine/ninja.git && \ - cd ninja && \ - git checkout v1.6.0 && \ - python ./configure.py --bootstrap && \ - ./ninja && \ - cp ./ninja /usr/bin/ && \ - cd .. && rm -rf ninja + cd ninja && \ + git checkout v1.6.0 && \ + python ./configure.py --bootstrap && \ + ./ninja && \ + cp ./ninja /usr/bin/ && \ + cd .. && rm -rf ninja WORKDIR /build ENTRYPOINT ["/dockcross/entrypoint.sh"] diff --git a/Makefile b/Makefile index f553801..d0722b6 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,9 @@ linux-x86: linux-x64: $(DOCKER) build -t $(IMAGE)-linux-x64 linux-x64 +linux-armv5: base linux-armv5/Dockerfile linux-armv5/Toolchain.cmake + $(DOCKER) build -t $(IMAGE)-linux-armv5 linux-armv5 + linux-armv6: base linux-armv6/Dockerfile linux-armv6/Toolchain.cmake $(DOCKER) build -t $(IMAGE)-linux-armv6 linux-armv6 @@ -34,6 +37,6 @@ windows-x64: base windows-x64/Dockerfile windows-x64/settings.mk base: Dockerfile $(DOCKER) build -t $(IMAGE)-base . -all: base android-arm darwin-x64 linux-x86 linux-x64 linux-armv6 linux-armv7 windows-x86 windows-x64 +all: base android-arm darwin-x64 linux-x86 linux-x64 linux-armv5 linux-armv6 linux-armv7 windows-x86 windows-x64 -.PHONY: all base android-arm darwin-x64 linux-x86 linux-x64 linux-armv6 linux-armv7 windows-x86 windows-x64 +.PHONY: all base android-arm darwin-x64 linux-x86 linux-x64 linux-armv5 linux-armv6 linux-armv7 windows-x86 windows-x64 diff --git a/README.rst b/README.rst index efb02e9..f65b193 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,91 @@ cross-compilers -=============== -Dockerfiles for cross compiling environments --------------------------------------------- +--------------- + +Dockerfiles for cross compiling in a Docker container. + +Features +======== + +* different toolchains for cross compiling +* commands in the container are run as the calling user, so that any created files have the expected ownership (ie. not root) +* make variables (`CC`, `LD` etc) are set to point to the appropriate tools in the container +* cmake and ninja are precompiled available with a toolchain file for cmake +* current directory is mounted as the container's workdir, `/build` +* works with boot2docker on OSX and Docker for Mac beta (1.11.1-beta12) + +Installation +============ + +This image is not intended to be run manually. Instead, there is a helper script which comes bundled with the image. + +To install the helper script, run the image with no arguments, and redirect the output to a file:: + + docker run CROSS_COMPILER_IMAGE_NAME > dockcross + chmod +x dockcross + mv dockcross ~/bin/ + +Usage +===== + +For the impatient, here's a one-liner to compile a hello world for armv7:: + + docker run thewtex/cross-compiler-linux-armv7 > dockcross && chmod +x dockcross && ./dockcross gcc test/C/hello.c -o hello_arm + +Note how invoking any toolchain command (make, gcc, etc...) is just a matter of prepending **dockcross** in the commandline: + +`dockcross [command] [args...]` + +Dockcross will thus execute the given command-line inside the container, along with all arguments passed after the command. + +Alternatively, if the command matches one of the dockcross built-in commands (see below), that will be executed locally. + + +Built-in commands +================= + +- `dockcross -- [command] [args...]`: Forces a command to run inside the container (in case of a name clash with a built-in command), use `--` before the command. +- `dockcross update-image`: Fetch the latest version of the docker image. +- `dockcross update-script`: Update the installed dockcross script with the one bundled in the image. +- `dockcross update`: Update both the docker image, and the dockcross script. + +Configuration +============= + +The following command-line options and environment variables are used. In all cases, the command-line option overrides the environment variable. + +### DOCKCROSS_CONFIG / --config + +This file is sourced if it exists. + +Default: `~/.dockcross` + +### DOCKCROSS_IMAGE / --image + +The docker image to run. + +Default: thewtex/cross-compiler-linux-armv7 + +### DOCKCROSS_ARGS / --args + +Extra arguments to pass to the `docker run` command. + +Examples +======== + +1. **dockcross make**: Build the Makefile in the current directory. +2. **dockcross cmake -Bbuild -H. -GNinja***: Run CMake with a build directory "build" for the CMakeLists.txt in the current directory and generate `ninja` files. +3. **dockcross ninja -Cbuild**: Run ninja in the generated build directory. +4. **dockcross bash -c 'find . -name \*.o | sort > objects.txt'** + +Note that commands are executed verbatim. If you require any shell processing for environment variable expansion or redirection, please use `bash -c 'command args...'`. + +--- + +Credits go to `sdt/docker-raspberry-pi-cross-compiler `_, who invented the base of this **dockcross** script. + + +CI status +--------- .. image:: https://circleci.com/gh/thewtex/cross-compilers/tree/master.svg?style=svg :target: https://circleci.com/gh/thewtex/cross-compilers/tree/master diff --git a/circle.yml b/circle.yml index b311642..dbec2ce 100644 --- a/circle.yml +++ b/circle.yml @@ -40,6 +40,7 @@ test: - make windows-x86: timeout: 3000 - docker run --rm -v ~/cross-compilers/test/:/usr/src/test:ro thewtex/cross-compiler-windows-x86 python /usr/src/test/run.py --emulator /usr/bin/wine --exe-suffix ".exe" + - docker run thewtex/cross-compiler-linux-armv7 > dockcross && chmod +x dockcross && ./dockcross gcc test/C/hello.c -o hello_arm deployment: hub: diff --git a/imagefiles/dockcross b/imagefiles/dockcross index dfccede..7a029bd 100755 --- a/imagefiles/dockcross +++ b/imagefiles/dockcross @@ -180,7 +180,7 @@ docker run -i -t --rm \ # # To install the dockcross helper, run the following commands: # -# docker run sdt4docker/raspberry-pi-cross-compiler > dockcross +# docker run thewtex/raspberry-pi-cross-compiler > dockcross # chmod +x dockcross # # You may then wish to move dockcross to somewhere in your path. diff --git a/linux-armv5/Dockerfile b/linux-armv5/Dockerfile new file mode 100644 index 0000000..7057ffe --- /dev/null +++ b/linux-armv5/Dockerfile @@ -0,0 +1,25 @@ +FROM thewtex/cross-compiler-base +MAINTAINER Matt McCormick "matt.mccormick@kitware.com" + +# This is for ARMv5 "legacy" devices which do not support hard float VFP instructions. +# https://wiki.debian.org/CrossToolchains +RUN dpkg --add-architecture armel && \ + apt-get update && \ + apt-get install -y crossbuild-essential-armel + +# The cross-compiling emulator +RUN apt-get update && apt-get install -y \ + qemu-user \ + qemu-user-static + +ENV CROSS_TRIPLE arm-linux-gnueabi +ENV CROSS_ROOT /usr/bin +ENV AS=/usr/bin/${CROSS_TRIPLE}-as \ + AR=/usr/bin/${CROSS_TRIPLE}-ar \ + CC=/usr/bin/${CROSS_TRIPLE}-gcc \ + CPP=/usr/bin/${CROSS_TRIPLE}-cpp \ + CXX=/usr/bin/${CROSS_TRIPLE}-g++ \ + LD=/usr/bin/${CROSS_TRIPLE}-ld + +ENV QEMU_LD_PREFIX ${CROSS_ROOT}/libc +ENV QEMU_SET_ENV "LD_LIBRARY_PATH=${CROSS_ROOT}/lib:${CROSS_ROOT}/libc/lib/${CROSS_TRIPLE}/" diff --git a/linux-armv5/Toolchain.cmake b/linux-armv5/Toolchain.cmake new file mode 100644 index 0000000..932ca15 --- /dev/null +++ b/linux-armv5/Toolchain.cmake @@ -0,0 +1,16 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR arm) + +set(cross_triple "arm-linux-gnueabi") + +set(CMAKE_C_COMPILER /usr/bin/${cross_triple}-gcc) +set(CMAKE_CXX_COMPILER /usr/bin/${cross_triple}-g++) +set(CMAKE_Fortran_COMPILER /usr/bin/${cross_triple}-gfortran) + +set(CMAKE_FIND_ROOT_PATH /usr/${cross_triple} /usr/${cross_triple}/libc/usr) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-arm) diff --git a/linux-armv6/Dockerfile b/linux-armv6/Dockerfile index dd8d587..870cc63 100644 --- a/linux-armv6/Dockerfile +++ b/linux-armv6/Dockerfile @@ -27,10 +27,14 @@ ENV AS=/usr/bin/${CROSS_TRIPLE}-as \ # of performance. # See: https://wiki.debian.org/RaspberryPi # We are also using the 4.7 version of the toolchain, so that glibc=2.13 -ENV RASPBERRYPI_TOOLS_COMMIT 9c3d7b6ac692498dd36fec2872e0b55f910baac1 -RUN curl -L https://github.com/raspberrypi/tools/archive/${RASPBERRYPI_TOOLS_COMMIT}.tar.gz | tar xvz --wildcards --no-anchored "*gcc-linaro-${CROSS_TRIPLE}-raspbian*" && \ - rsync -av /usr/src/tools-${RASPBERRYPI_TOOLS_COMMIT}/arm-bcm2708/gcc-linaro-${CROSS_TRIPLE}-raspbian/ /usr/ && \ - rm -rf /usr/src/tools-${RASPBERRYPI_TOOLS_COMMIT} + +# Instead of cloning the whole repo (>1GB at the of writing this), we want to do a so-called "sparse checkout" with "shallow cloning": +# https://stackoverflow.com/questions/600079/is-there-any-way-to-clone-a-git-repositorys-sub-directory-only/13738951#13738951 + +RUN mkdir rpi_tools && cd rpi_tools && git init && git remote add -f origin https://github.com/raspberrypi/tools && \ + git config core.sparseCheckout true && echo "arm-bcm2708/gcc-linaro-${CROSS_TRIPLE}-raspbian" >> .git/info/sparse-checkout && \ + git pull --depth=1 origin master && rsync -av arm-bcm2708/gcc-linaro-${CROSS_TRIPLE}-raspbian/ /usr/ && rm -rf ../rpi_tools + # Allow dynamically linked executables to run with qemu-arm ENV QEMU_LD_PREFIX ${CROSS_ROOT}/libc ENV QEMU_SET_ENV "LD_LIBRARY_PATH=${CROSS_ROOT}/lib:${CROSS_ROOT}/libc/lib/${CROSS_TRIPLE}/"