From 08ead78f41412d7f67c36e86ef799c31673b2960 Mon Sep 17 00:00:00 2001 From: midchildan Date: Thu, 28 Feb 2019 20:09:31 +0900 Subject: [PATCH] qemu-arm: Add support for TravisCI --- .circleci/config.yml | 6 +++-- .travis.yml | 61 ++++++++++++++++++++++++++++++++++++++++---- default.nix | 26 +++++++++++++++++++ nix/frankenlibc.nix | 25 ++++++++++++++++++ nix/qemu-circle.nix | 41 +++++++++++++++++++++++++++++ tools/qemu-arm.sh | 17 +++++++++--- 6 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 default.nix create mode 100644 nix/frankenlibc.nix create mode 100644 nix/qemu-circle.nix diff --git a/.circleci/config.yml b/.circleci/config.yml index 1cb3375ba..2977ab598 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -147,7 +147,9 @@ workflows: jobs: - linux-linux - linux-netbsd - - qemu-arm-linux - - qemu-arm-netbsd + # FIXME: Forked version of QEMU is needed + # - qemu-arm-linux + # TODO: Investigate netbsd support for qemu-arm + # - qemu-arm-netbsd - freebsd-linux - freebsd-netbsd diff --git a/.travis.yml b/.travis.yml index 00cf1c155..2c2cfaefb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,59 @@ -language: c +language: nix -compiler: - - gcc - - clang +env: + global: + # XXX: Nix on Travis uses the master branch of the nixpkgs repo, meaning we + # need to pin nixpkgs to a specific version if we want to avoid frequent + # rebuilds of dependant packages. + # + # TODO: should ideally point to the latest stable release. + # However, we currently use the unstable release (@ 2019-03-03) since we + # depend on NixOS/nixpkgs#52146, which hasn't been merged into stable yet. + # It should be possible to use stable once 19.09 is out. + - NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/34aa254f9ebf5899636a9927ceefbc9df80230f4.tar.gz + +matrix: + include: + # FIXME: Some of these are disabled for now; additional work is required + # for nix support. It didn't even work well without nix anyways because + # excessive log output caused Travis to terminate the build process. + # + # - name: "GCC" + # env: BUILD_TARGET=frankenlibc-gcc + # - name: "Clang" + # env: BUILD_TARGET=frankenlibc-clang + - name: "QEMU ARM" + env: BUILD_TARGET=frankenlibc-arm + +git: + # XXX: Submodules have to be fetched manually since it frequently times out. + submodules: false + +cache: + timeout: 1000 + directories: + - $HOME/nix.store + # XXX: Beware. Desperate attempt to cache the lkl repository. + - $TRAVIS_BUILD_DIR/.git/modules + +before_cache: + - mkdir -p $HOME/nix.store + - | + nix copy --to file://$HOME/nix.store -f default.nix \ + "$BUILD_TARGET".buildInputs \ + "$BUILD_TARGET".nativeBuildInputs \ + "$BUILD_TARGET".depsBuildBuild + +before_install: + - travis_wait 30 git submodule update --init --recursive + - mkdir -p $HOME/.config/nix + - | + # XXX: We write the configuration line-by-line, since Travis doesn't seem + # to recognize heredoc delimiters for some reason. + echo "substituters = file://$HOME/nix.store https://cache.nixos.org/" \ + >> ~/.config/nix/nix.conf + echo "require-sigs = false" \ + >> ~/.config/nix/nix.conf script: - - ./build.sh + - nix-build -A "$BUILD_TARGET" diff --git a/default.nix b/default.nix new file mode 100644 index 000000000..c4cfdcd20 --- /dev/null +++ b/default.nix @@ -0,0 +1,26 @@ +{ pkgs ? import {} }: + +with pkgs; + +let + callPackage = lib.callPackageWith (pkgs // self); + + self = { + frankenlibc-gcc = callPackage ./nix/frankenlibc.nix { }; + + frankenlibc-clang = callPackage ./nix/frankenlibc.nix { + stdenv = clangStdenv; + }; + + frankenlibc-arm = callPackage ./nix/frankenlibc.nix { + # XXX: We need newlib-nano instead of newlib to compile. See + # NixOS/nixpkgs#51907 for details. + stdenv = + let armStdenv = mkStdenvNoLibs pkgsCross.arm-embedded.stdenv; + in overrideCC armStdenv gcc-arm-embedded; + }; + + qemu-circle = callPackage ./nix/qemu-circle.nix { }; + }; + +in self diff --git a/nix/frankenlibc.nix b/nix/frankenlibc.nix new file mode 100644 index 000000000..d1cb92bfe --- /dev/null +++ b/nix/frankenlibc.nix @@ -0,0 +1,25 @@ +{ stdenv, lib, buildPackages, bc, e2fsprogs, python, zlib, qemu-circle }: + +stdenv.mkDerivation ({ + name = "frankenlibc"; + + src = lib.cleanSource ../.; + + depsBuildBuild = [ buildPackages.stdenv.cc zlib ]; + nativeBuildInputs = + [ bc e2fsprogs python ] ++ lib.optionals stdenv.isAarch32 [ qemu-circle ]; + + buildFlags = if stdenv.isAarch32 then [ "-k" "linux" "qemu-arm" ] else []; + + # TODO: Separate checkPhase from buildPhase. + buildPhase = "./build.sh $buildFlags"; + + # FIXME: The copied output is not directly usable, since there are absolute + # paths everywhere. + installPhase = "cp -r . $out"; +} +// lib.optionalAttrs stdenv.isAarch32 { + # XXX: Workaround to prevent Travis from terminating the build by suppressing + # log ouput. Travis terminates any build that produce logs exceeding 4MB. + fixupPhase = ":"; +}) diff --git a/nix/qemu-circle.nix b/nix/qemu-circle.nix new file mode 100644 index 000000000..221e5fbb5 --- /dev/null +++ b/nix/qemu-circle.nix @@ -0,0 +1,41 @@ +{ stdenv, fetchurl, fetchFromGitHub, overrideCC, qemu, gcc6, SDL }: + +let + qemu-circle = qemu.override { + hostCpuTargets = [ "arm-softmmu" ]; + pulseSupport = false; + sdlSupport = false; SDL2 = SDL; + gtkSupport = false; + vncSupport = false; + smartcardSupport = false; + spiceSupport = false; + xenSupport = false; + cephSupport = false; + openGLSupport = false; + virglSupport = false; + smbdSupport = false; + }; + + diffForCommit = commit: "https://github.com/qemu/qemu/commit/${commit}.diff"; +in + qemu-circle.overrideAttrs (old: rec { + name = "qemu-circle-${version}"; + version = "2.4.1"; + sha256 = "19936r6x7wal09zh0f1s5y32v4k4z5nmnfb2jf0padmff3808jl9"; + src = fetchFromGitHub { + owner = "rsta2"; + repo = "qemu"; + rev = "7a24a5a051ea83529b057fd18c76ca40eb717392"; + fetchSubmodules = true; + inherit sha256; + }; + + patches = builtins.tail old.patches ++ [ + (fetchurl { + url = diffForCommit "75e5b70e6b5dcc4f2219992d7cffa462aa406af0"; + sha256 = "0a9a09xy4iy6gnmhlbgj28pvzxwp7h165s3rvpc9n6b7lbm0dibj"; + }) + ]; + + stdenv = overrideCC stdenv gcc6; + }) diff --git a/tools/qemu-arm.sh b/tools/qemu-arm.sh index 01e22540a..d12ea6088 100755 --- a/tools/qemu-arm.sh +++ b/tools/qemu-arm.sh @@ -1,20 +1,31 @@ #!/bin/bash -LKL_TAP="${LKL_TAP:-tap0}" +LKL_TAP="${LKL_TAP:-none}" LKL_DEBUG="${LKL_DEBUG:-1}" LKL_QEMU_CMDLINE= BIN_PATH="$1" main() { - sudo env PATH="$PATH" \ + if [[ "$LKL_TAP" != "none" ]]; then + sudo env PATH="$PATH" \ + qemu-system-arm \ + $LKL_QEMU_ARGS \ + -M raspi2 \ + -nographic \ + -device usb-net,vlan=0 \ + -net tap,vlan=0,ifname="$LKL_TAP",script=no,downscript=no \ + -append "$(build_qemu_cmdline "$@")" \ + -semihosting -kernel "$BIN_PATH" + else qemu-system-arm \ $LKL_QEMU_ARGS \ -M raspi2 \ -nographic \ -device usb-net,vlan=0 \ - -net tap,vlan=0,ifname="$LKL_TAP",script=no,downscript=no \ + -net user,vlan=0 \ -append "$(build_qemu_cmdline "$@")" \ -semihosting -kernel "$BIN_PATH" + fi } build_qemu_cmdline() {