From 51fa228fc300bd98f622e6ec5c15b7c8a9e60c26 Mon Sep 17 00:00:00 2001 From: Christopher Larson Date: Thu, 3 Nov 2016 11:09:59 -0700 Subject: [PATCH] tcmode: merge in codebench.bbclass We were hitting issues due to non-deterministic ordering of ConfigParsed event handlers between codebench.bbclass and the tcmode. To avoid this, consolidate the two and use a single handler. Signed-off-by: Christopher Larson --- classes/codebench.bbclass | 75 ------------------ .../include/tcmode-external-sourcery.inc | 79 ++++++++++++++++++- 2 files changed, 76 insertions(+), 78 deletions(-) delete mode 100644 classes/codebench.bbclass diff --git a/classes/codebench.bbclass b/classes/codebench.bbclass deleted file mode 100644 index 94bef4c..0000000 --- a/classes/codebench.bbclass +++ /dev/null @@ -1,75 +0,0 @@ -# If the user hasn't set EXTERNAL_TOOLCHAIN, but CODEBENCH_PATH is set, then -# we automatically set both EXTERNAL_TOOLCHAIN and EXTERNAL_TARGET_SYS based -# on the installed toolchains in CODEBENCH_PATH/../toolchains. -CODEBENCH_PATH ?= "" -CODEBENCH_TOOLCHAINS_PATH ?= "${CODEBENCH_PATH}/../toolchains" - -def auto_codebench_path_fixup(exttc, d): - """Fixups for common issues with EXTERNAL_TOOLCHAIN with CodeBench.""" - if os.path.exists(os.path.join(exttc, 'codebench')): - newtc = os.path.join(exttc, 'codebench') - if not os.path.exists(os.path.join(newtc, '..', 'toolchains')): - bb.warn('EXTERNAL_TOOLCHAIN was set to the root of a codebench install, not the toolchain path') - bb.warn('Adjusted EXTERNAL_TOOLCHAIN from `{}` to `{}`'.format(exttc, newtc)) - exttc = newtc - d.setVar('EXTERNAL_TOOLCHAIN', exttc) - - if os.path.exists(os.path.join(exttc, '..', 'toolchains')): - bb.warn('Detected CodeBench installation, but CODEBENCH_PATH is not set') - bb.warn('Adjusted CODEBENCH_PATH to `{}` and removed EXTERNAL_TOOLCHAIN'.format(exttc)) - d.setVar('CODEBENCH_PATH', exttc) - d.setVar('EXTERNAL_TOOLCHAIN', '') - -def set_vars_from_toolchains(codebench_path, d): - toolchains_path = d.getVar('CODEBENCH_TOOLCHAINS_PATH', True) - if not os.path.exists(toolchains_path): - if len(os.listdir(os.path.join(codebench_path, 'bin'))) > 1: - bb.warn('CODEBENCH_PATH is set, but the expected toolchains path ({}) does not exist. Defaulting EXTERNAL_TOOLCHAIN to CODEBENCH_PATH, assuming an old codebench version.'.format(toolchains_path)) - else: - bb.fatal('Expected toolchains path `{}` does not exist, please ensure that CODEBENCH_PATH is set to a valid CodeBench installation'.format(toolchains_path)) - - required_version = d.getVar('SOURCERY_VERSION_REQUIRED', True) - if required_version: - required_version = required_version.split('-', 1)[0] - - subdirs = os.listdir(toolchains_path) - triplets, toolchain_subdir = [], None - for triplet in d.getVar('EXTERNAL_TARGET_SYSTEMS', True).split(): - if required_version: - expected_subdir = triplet + '.' + required_version - if expected_subdir in subdirs: - triplets.append(triplet) - toolchain_subdir = expected_subdir - else: - for subdir in subdirs: - if subdir.startswith(triplet + '.'): - triplets.append(triplet) - toolchain_subdir = subdir - - if triplets: - break - - if len(triplets) > 1: - bb.fatal('Error: unable to determine which toolchain to use, as multiple are available ({}). Please set EXTERNAL_TOOLCHAIN manually to the appropriate path in `{}`'.format(', '.join(triplets), toolchains_path)) - elif not triplets: - bb.fatal('Unable to locate appropriate toolchain in `{}`, please set EXTERNAL_TOOLCHAIN to the correct toolchain path, or install the required CodeBench version'.format(toolchains_path)) - else: - d.setVar('EXTERNAL_TARGET_SYS', triplets[0]) - d.setVar('EXTERNAL_TOOLCHAIN', os.path.join(toolchains_path, toolchain_subdir)) - -python codebench_check () { - codebench_path = d.getVar('CODEBENCH_PATH', True) - exttc = d.getVar('EXTERNAL_TOOLCHAIN', True) - if exttc: - if codebench_path: - bb.warn('Both EXTERNAL_TOOLCHAIN and CODEBENCH_PATH are set. Ignoring CODEBENCH_PATH in preference to EXTERNAL_TOOLCHAIN') - return - else: - auto_codebench_path_fixup(exttc, d) - codebench_path = d.getVar('CODEBENCH_PATH', True) - - if codebench_path: - set_vars_from_toolchains(codebench_path, d) -} -codebench_check[eventmask] = "bb.event.ConfigParsed" -addhandler codebench_check diff --git a/conf/distro/include/tcmode-external-sourcery.inc b/conf/distro/include/tcmode-external-sourcery.inc index cd73d30..6d77287 100644 --- a/conf/distro/include/tcmode-external-sourcery.inc +++ b/conf/distro/include/tcmode-external-sourcery.inc @@ -4,6 +4,12 @@ EXTERNAL_TOOLCHAIN ?= "UNDEFINED" +# If the user hasn't set EXTERNAL_TOOLCHAIN, but CODEBENCH_PATH is set, then +# we automatically set both EXTERNAL_TOOLCHAIN and EXTERNAL_TARGET_SYS based +# on the installed toolchains in CODEBENCH_PATH/../toolchains. +CODEBENCH_PATH ?= "" +CODEBENCH_TOOLCHAINS_PATH ?= "${CODEBENCH_PATH}/../toolchains" + # When using a 32-bit external toolchain, we need 32 bit pseudo HAS_64BIT_TOOLCHAIN = "${@'1' if '${BUILD_ARCH}' == 'x86_64' and os.path.exists('${EXTERNAL_TOOLCHAIN}/${BUILD_SYS}-gnu') else '0'}" NO32LIBS ?= "${HAS_64BIT_TOOLCHAIN}" @@ -50,9 +56,6 @@ PREFERRED_PROVIDER_linux-libc-headers = "linux-libc-headers-external" # Support use of an external toolchain with the SDK/ADE/etc TOOLCHAIN_TARGET_TASK_append = " sdk-env-external-toolchain" -# Set our vars based on the codebench path, if available -INHERIT += "codebench" - # Pull in our utility functions for use elsewhere INHERIT += "external-common" @@ -173,6 +176,8 @@ python toolchain_metadata_setup () { if var in d: testenv[var] = d.getVar(var, True) + codebench_check(d) + with tempfile.NamedTemporaryFile(suffix='.c') as f: try: subprocess.check_output([d.expand('${EXTERNAL_TOOLCHAIN}/bin/${EXTERNAL_TARGET_SYS}-gcc'), '-msgxx-glibc', '-E', f.name], stderr=subprocess.STDOUT, env=testenv, cwd=d.getVar('TOPDIR', True)) @@ -184,6 +189,74 @@ python toolchain_metadata_setup () { toolchain_metadata_setup[eventmask] = "bb.event.ConfigParsed" addhandler toolchain_metadata_setup +def codebench_check(d): + codebench_path = d.getVar('CODEBENCH_PATH', True) + exttc = d.getVar('EXTERNAL_TOOLCHAIN', True) + if exttc and exttc != 'UNDEFINED': + if codebench_path: + bb.warn('Both EXTERNAL_TOOLCHAIN and CODEBENCH_PATH are set. Ignoring CODEBENCH_PATH in preference to EXTERNAL_TOOLCHAIN') + return + else: + auto_codebench_path_fixup(exttc, d) + codebench_path = d.getVar('CODEBENCH_PATH', True) + + if codebench_path: + set_vars_from_toolchains(codebench_path, d) + +def auto_codebench_path_fixup(exttc, d): + """Fixups for common issues with EXTERNAL_TOOLCHAIN with CodeBench.""" + if os.path.exists(os.path.join(exttc, 'codebench')): + newtc = os.path.join(exttc, 'codebench') + if not os.path.exists(os.path.join(newtc, '..', 'toolchains')): + bb.warn('EXTERNAL_TOOLCHAIN was set to the root of a codebench install, not the toolchain path') + bb.warn('Adjusted EXTERNAL_TOOLCHAIN from `{}` to `{}`'.format(exttc, newtc)) + exttc = newtc + d.setVar('EXTERNAL_TOOLCHAIN', exttc) + + if os.path.exists(os.path.join(exttc, '..', 'toolchains')): + bb.warn('Detected CodeBench installation, but CODEBENCH_PATH is not set') + bb.warn('Adjusted CODEBENCH_PATH to `{}` and removed EXTERNAL_TOOLCHAIN'.format(exttc)) + d.setVar('CODEBENCH_PATH', exttc) + d.setVar('EXTERNAL_TOOLCHAIN', '') + +def set_vars_from_toolchains(codebench_path, d): + toolchains_path = d.getVar('CODEBENCH_TOOLCHAINS_PATH', True) + if not os.path.exists(toolchains_path): + if len(os.listdir(os.path.join(codebench_path, 'bin'))) > 1: + bb.warn('CODEBENCH_PATH is set, but the expected toolchains path ({}) does not exist. Defaulting EXTERNAL_TOOLCHAIN to CODEBENCH_PATH, assuming an old codebench version.'.format(toolchains_path)) + else: + bb.fatal('Expected toolchains path `{}` does not exist, please ensure that CODEBENCH_PATH is set to a valid CodeBench installation'.format(toolchains_path)) + + required_version = d.getVar('SOURCERY_VERSION_REQUIRED', True) + if required_version: + required_version = required_version.split('-', 1)[0] + + subdirs = os.listdir(toolchains_path) + triplets, toolchain_subdir = [], None + for triplet in d.getVar('EXTERNAL_TARGET_SYSTEMS', True).split(): + if required_version: + expected_subdir = triplet + '.' + required_version + if expected_subdir in subdirs: + triplets.append(triplet) + toolchain_subdir = expected_subdir + else: + for subdir in subdirs: + if subdir.startswith(triplet + '.'): + triplets.append(triplet) + toolchain_subdir = subdir + + if triplets: + break + + if len(triplets) > 1: + bb.fatal('Error: unable to determine which toolchain to use, as multiple are available ({}). Please set EXTERNAL_TOOLCHAIN manually to the appropriate path in `{}`'.format(', '.join(triplets), toolchains_path)) + elif not triplets: + bb.fatal('Unable to locate appropriate toolchain in `{}`, please set EXTERNAL_TOOLCHAIN to the correct toolchain path, or install the required CodeBench version'.format(toolchains_path)) + else: + d.setVar('EXTERNAL_TARGET_SYS', triplets[0]) + d.setVar('EXTERNAL_TOOLCHAIN', os.path.join(toolchains_path, toolchain_subdir)) + + python toolchain_sanity_check () { d = e.data external_toolchain = d.getVar('EXTERNAL_TOOLCHAIN', True)