summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Rossi <nathan@nathanrossi.com>2019-08-28 05:06:29 +0000
committerArmin Kuster <akuster808@gmail.com>2019-08-30 15:29:47 -0700
commitedfa71c57f63eb093e2a24bf78523d938881688b (patch)
treeb6142b1b3a4ba8e5bbba683cb684fa5e12b1003e
parenta84bdc8c46ee3b49137b7d064c77542e39bfc821 (diff)
downloadopenembedded-core-contrib-edfa71c57f63eb093e2a24bf78523d938881688b.tar.gz
openembedded-core-contrib-edfa71c57f63eb093e2a24bf78523d938881688b.tar.bz2
openembedded-core-contrib-edfa71c57f63eb093e2a24bf78523d938881688b.zip
gcc-cross: Add do_check task for executing gcc test suite
Add a do_check task and supporting configuration to implement execution of the gcc compiler test suite. The test suite requires execution of compiled programs. The implementation provided allows for execution testing against a host via SSH or within the local build environment using qemu linux-user execution. The selection of execution is done via the BUILD_TEST_TARGET variable, and configuration of the remote host is done with the BUILD_TEST_HOST, BUILD_TEST_HOST_USER and BUILD_TEST_HOST_PORT variables. By default the do_check task will execute all check targets, this can be changed by setting MAKE_CHECK_TARGETS to the desired test suite target (e.g. check-gcc or check-g++). Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta/recipes-devtools/gcc/gcc-cross.inc41
-rw-r--r--meta/recipes-devtools/gcc/gcc-testsuite.inc106
2 files changed, 147 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-cross.inc b/meta/recipes-devtools/gcc/gcc-cross.inc
index 6222c2e8c9..f9534340d2 100644
--- a/meta/recipes-devtools/gcc/gcc-cross.inc
+++ b/meta/recipes-devtools/gcc/gcc-cross.inc
@@ -221,3 +221,44 @@ python do_gcc_stash_builddir_setscene () {
sstate_setscene(d)
}
addtask do_gcc_stash_builddir_setscene
+
+require gcc-testsuite.inc
+
+check_prepare_sysroot () {
+ if [ ! -s ${RECIPE_SYSROOT}${target_includedir}/limits.h ]; then
+ # this file was created by the configure task, but is replaced by the
+ # libc version when populating the sysroot for the do_check task
+ rm ${RECIPE_SYSROOT}${target_includedir}/limits.h
+ fi
+}
+
+EXTRA_OEMAKE_prepend_task-check = "${PARALLEL_MAKE} "
+
+MAKE_CHECK_TARGETS ??= "check-gcc check-g++ check-lto"
+
+python () {
+ # crosssdk deps have different virtual targets
+ if bb.data.inherits_class('crosssdk', d):
+ d.appendVarFlag("do_check", "depends", " virtual/nativesdk-${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+ else:
+ d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+}
+
+# specific host and target dependencies required for test suite running
+do_check[depends] += "dejagnu-native:do_populate_sysroot expect-native:do_populate_sysroot"
+do_check[depends] += "virtual/libc:do_populate_sysroot"
+# only depend on qemu if targeting linux user execution
+do_check[depends] += "${@'qemu-native:do_populate_sysroot' if "user" in d.getVar('BUILD_TEST_TARGET') else ''}"
+# check_prepare_sysroot is before extend in order to perform the limits.h removal
+do_check[prefuncs] += "check_prepare_sysroot"
+do_check[prefuncs] += "extend_recipe_sysroot"
+do_check[prefuncs] += "check_prepare"
+do_check[dirs] = "${WORKDIR}/dejagnu ${B}"
+do_check[nostamp] = "1"
+do_check() {
+ export DEJAGNU="${WORKDIR}/dejagnu/site.exp"
+
+ oe_runmake -i -C ${B}/gcc ${MAKE_CHECK_TARGETS} RUNTESTFLAGS="${MAKE_CHECK_BOARDARGS}"
+}
+addtask check after do_compile do_populate_sysroot
+
diff --git a/meta/recipes-devtools/gcc/gcc-testsuite.inc b/meta/recipes-devtools/gcc/gcc-testsuite.inc
new file mode 100644
index 0000000000..f9924f2d86
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-testsuite.inc
@@ -0,0 +1,106 @@
+inherit qemu
+
+BUILD_TEST_TARGET ??= "user"
+BUILD_TEST_HOST ??= "localhost"
+BUILD_TEST_HOST_USER ??= "root"
+BUILD_TEST_HOST_PORT ??= "2222"
+
+MAKE_CHECK_BOARDFLAGS ??= ""
+MAKE_CHECK_BOARDARGS ??= "--target_board=${BUILD_TEST_TARGET}${MAKE_CHECK_BOARDFLAGS}"
+
+python () {
+ # Provide the targets compiler args via targets options. This allows dejagnu to
+ # correctly mark incompatible tests as UNSUPPORTED (e.g. needs soft-float
+ # but running on hard-float target).
+ #
+ # These options are called "multilib_flags" within the gcc test suite. Most
+ # architectures handle these options in a sensible way such that tests that
+ # are incompatible with the provided multilib are marked as UNSUPPORTED.
+ #
+ # Note: multilib flags are added to the compile command after the args
+ # provided by any test (through dg-options), CFLAGS_FOR_TARGET is always
+ # added to the compile command before any other args but is not interpted
+ # as options like multilib flags.
+ #
+ # i686, x86-64 and aarch64 are special, since most toolchains built for
+ # these targets don't do multilib the tests do not get correctly marked as
+ # UNSUPPORTED. More importantly the test suite itself does not handle
+ # overriding the multilib flags where it could (like other archs do). As
+ # such do not pass the target compiler args for these targets.
+ args = d.getVar("TUNE_CCARGS").split()
+ if d.getVar("TUNE_ARCH") in ["i686", "x86_64", "aarch64"]:
+ args = []
+ d.setVar("MAKE_CHECK_BOARDFLAGS", ("/" + "/".join(args)) if len(args) != 0 else "")
+}
+
+python check_prepare() {
+ def generate_qemu_linux_user_config(d):
+ content = []
+ content.append('load_generic_config "sim"')
+ content.append('load_base_board_description "basic-sim"')
+ content.append('process_multilib_options ""')
+
+ # qemu args
+ qemu_binary = qemu_target_binary(d)
+ if not qemu_binary:
+ bb.fatal("Missing target qemu linux-user binary")
+
+ args = []
+ # QEMU_OPTIONS is not always valid due to -cross recipe
+ args += ["-r", d.getVar("OLDEST_KERNEL")]
+ # enable all valid instructions, since the test suite itself does not
+ # limit itself to the target cpu options.
+ # - valid for x86*, powerpc, arm, arm64
+ if qemu_binary.lstrip("qemu-") in ["x86_64", "i386", "ppc", "arm", "aarch64"]:
+ args += ["-cpu", "max"]
+
+ sysroot = d.getVar("RECIPE_SYSROOT")
+ args += ["-L", sysroot]
+ # lib paths are static here instead of using $libdir since this is used by a -cross recipe
+ libpaths = [sysroot + "/usr/lib", sysroot + "/lib"]
+ args += ["-E", "LD_LIBRARY_PATH={0}".format(":".join(libpaths))]
+
+ content.append('set_board_info is_simulator 1')
+ content.append('set_board_info sim "{0}"'.format(qemu_binary))
+ content.append('set_board_info sim,options "{0}"'.format(" ".join(args)))
+
+ # target build/test config
+ content.append('set_board_info target_install {%s}' % d.getVar("TARGET_SYS"))
+ content.append('set_board_info ldscript ""')
+ #content.append('set_board_info needs_status_wrapper 1') # qemu-linux-user return codes work, and abort works fine
+ content.append('set_board_info gcc,stack_size 16834')
+ content.append('set_board_info gdb,nosignals 1')
+ content.append('set_board_info gcc,timeout 60')
+
+ return "\n".join(content)
+
+ def generate_remote_ssh_linux_config(d):
+ content = []
+ content.append('load_generic_config "unix"')
+ content.append("set_board_info hostname {0}".format(d.getVar("BUILD_TEST_HOST")))
+ content.append("set_board_info username {0}".format(d.getVar("BUILD_TEST_HOST_USER")))
+
+ port = d.getVar("BUILD_TEST_HOST_PORT")
+ content.append("set_board_info rsh_prog \"/usr/bin/ssh -p {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no\"".format(port))
+ content.append("set_board_info rcp_prog \"/usr/bin/scp -P {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no\"".format(port))
+
+ return "\n".join(content)
+
+ dejagnudir = d.expand("${WORKDIR}/dejagnu")
+ if not os.path.isdir(dejagnudir):
+ os.makedirs(dejagnudir)
+
+ # write out target qemu board config
+ with open(os.path.join(dejagnudir, "user.exp"), "w") as f:
+ f.write(generate_qemu_linux_user_config(d))
+
+ # write out target ssh board config
+ with open(os.path.join(dejagnudir, "ssh.exp"), "w") as f:
+ f.write(generate_remote_ssh_linux_config(d))
+
+ # generate site.exp to provide boards
+ with open(os.path.join(dejagnudir, "site.exp"), "w") as f:
+ f.write("lappend boards_dir {0}\n".format(dejagnudir))
+ f.write("set CFLAGS_FOR_TARGET \"{0}\"\n".format(d.getVar("TOOLCHAIN_OPTIONS")))
+}
+