Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # Extensible SDK |
| 2 | |
| 3 | inherit populate_sdk_base |
| 4 | |
| 5 | # NOTE: normally you cannot use task overrides for this kind of thing - this |
| 6 | # only works because of get_sdk_ext_rdepends() |
| 7 | |
| 8 | TOOLCHAIN_HOST_TASK_task-populate-sdk-ext = " \ |
| 9 | meta-environment-extsdk-${MACHINE} \ |
| 10 | " |
| 11 | |
| 12 | TOOLCHAIN_TARGET_TASK_task-populate-sdk-ext = "" |
| 13 | |
| 14 | SDK_RDEPENDS_append_task-populate-sdk-ext = " ${SDK_TARGETS}" |
| 15 | |
| 16 | SDK_RELOCATE_AFTER_INSTALL_task-populate-sdk-ext = "0" |
| 17 | |
| 18 | SDK_LOCAL_CONF_WHITELIST ?= "" |
| 19 | SDK_LOCAL_CONF_BLACKLIST ?= "CONF_VERSION BB_NUMBER_THREADS PARALLEL_MAKE PRSERV_HOST" |
| 20 | SDK_INHERIT_BLACKLIST ?= "buildhistory icecc" |
| 21 | SDK_UPDATE_URL ?= "" |
| 22 | |
| 23 | SDK_TARGETS ?= "${PN}" |
| 24 | OE_INIT_ENV_SCRIPT ?= "oe-init-build-env" |
| 25 | |
| 26 | # The files from COREBASE that you want preserved in the COREBASE copied |
| 27 | # into the sdk. This allows someone to have their own setup scripts in |
| 28 | # COREBASE be preserved as well as untracked files. |
| 29 | COREBASE_FILES ?= " \ |
| 30 | oe-init-build-env \ |
| 31 | oe-init-build-env-memres \ |
| 32 | scripts \ |
| 33 | LICENSE \ |
| 34 | .templateconf \ |
| 35 | " |
| 36 | |
| 37 | SDK_DIR_task-populate-sdk-ext = "${WORKDIR}/sdk-ext" |
| 38 | B_task-populate-sdk-ext = "${SDK_DIR}" |
| 39 | TOOLCHAIN_OUTPUTNAME_task-populate-sdk-ext = "${SDK_NAME}-toolchain-ext-${SDK_VERSION}" |
| 40 | |
| 41 | SDK_TITLE_task-populate-sdk-ext = "${@d.getVar('DISTRO_NAME', True) or d.getVar('DISTRO', True)} Extensible SDK" |
| 42 | |
| 43 | python copy_buildsystem () { |
| 44 | import re |
| 45 | import oe.copy_buildsystem |
| 46 | |
| 47 | oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT', True) |
| 48 | |
| 49 | conf_bbpath = '' |
| 50 | conf_initpath = '' |
| 51 | core_meta_subdir = '' |
| 52 | |
| 53 | # Copy in all metadata layers + bitbake (as repositories) |
| 54 | buildsystem = oe.copy_buildsystem.BuildSystem(d) |
| 55 | baseoutpath = d.getVar('SDK_OUTPUT', True) + '/' + d.getVar('SDKPATH', True) |
| 56 | layers_copied = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers') |
| 57 | |
| 58 | sdkbblayers = [] |
| 59 | corebase = os.path.basename(d.getVar('COREBASE', True)) |
| 60 | for layer in layers_copied: |
| 61 | if corebase == os.path.basename(layer): |
| 62 | conf_bbpath = os.path.join('layers', layer, 'bitbake') |
| 63 | else: |
| 64 | sdkbblayers.append(layer) |
| 65 | |
| 66 | for path in os.listdir(baseoutpath + '/layers'): |
| 67 | relpath = os.path.join('layers', path, oe_init_env_script) |
| 68 | if os.path.exists(os.path.join(baseoutpath, relpath)): |
| 69 | conf_initpath = relpath |
| 70 | |
| 71 | relpath = os.path.join('layers', path, 'scripts', 'devtool') |
| 72 | if os.path.exists(os.path.join(baseoutpath, relpath)): |
| 73 | scriptrelpath = os.path.dirname(relpath) |
| 74 | |
| 75 | relpath = os.path.join('layers', path, 'meta') |
| 76 | if os.path.exists(os.path.join(baseoutpath, relpath, 'lib', 'oe')): |
| 77 | core_meta_subdir = relpath |
| 78 | |
| 79 | d.setVar('oe_init_build_env_path', conf_initpath) |
| 80 | d.setVar('scriptrelpath', scriptrelpath) |
| 81 | |
| 82 | # Write out config file for devtool |
| 83 | import ConfigParser |
| 84 | config = ConfigParser.SafeConfigParser() |
| 85 | config.add_section('General') |
| 86 | config.set('General', 'bitbake_subdir', conf_bbpath) |
| 87 | config.set('General', 'init_path', conf_initpath) |
| 88 | config.set('General', 'core_meta_subdir', core_meta_subdir) |
| 89 | config.add_section('SDK') |
| 90 | config.set('SDK', 'sdk_targets', d.getVar('SDK_TARGETS', True)) |
| 91 | updateurl = d.getVar('SDK_UPDATE_URL', True) |
| 92 | if updateurl: |
| 93 | config.set('SDK', 'updateserver', updateurl) |
| 94 | bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf')) |
| 95 | with open(os.path.join(baseoutpath, 'conf', 'devtool.conf'), 'w') as f: |
| 96 | config.write(f) |
| 97 | |
| 98 | # Create a layer for new recipes / appends |
| 99 | bbpath = d.getVar('BBPATH', True) |
| 100 | bb.process.run(['devtool', '--bbpath', bbpath, '--basepath', baseoutpath, 'create-workspace', '--create-only', os.path.join(baseoutpath, 'workspace')]) |
| 101 | |
| 102 | # Create bblayers.conf |
| 103 | bb.utils.mkdirhier(baseoutpath + '/conf') |
| 104 | with open(baseoutpath + '/conf/bblayers.conf', 'w') as f: |
| 105 | f.write('# WARNING: this configuration has been automatically generated and in\n') |
| 106 | f.write('# most cases should not be edited. If you need more flexibility than\n') |
| 107 | f.write('# this configuration provides, it is strongly suggested that you set\n') |
| 108 | f.write('# up a proper instance of the full build system and use that instead.\n\n') |
| 109 | |
| 110 | f.write('LCONF_VERSION = "%s"\n\n' % d.getVar('LCONF_VERSION', False)) |
| 111 | f.write('BBPATH = "$' + '{TOPDIR}"\n') |
| 112 | f.write('SDKBASEMETAPATH = "$' + '{TOPDIR}"\n') |
| 113 | f.write('BBLAYERS := " \\\n') |
| 114 | for layerrelpath in sdkbblayers: |
| 115 | f.write(' $' + '{SDKBASEMETAPATH}/layers/%s \\\n' % layerrelpath) |
| 116 | f.write(' $' + '{SDKBASEMETAPATH}/workspace \\\n') |
| 117 | f.write(' "\n') |
| 118 | |
| 119 | # Create local.conf |
| 120 | local_conf_whitelist = (d.getVar('SDK_LOCAL_CONF_WHITELIST', True) or '').split() |
| 121 | local_conf_blacklist = (d.getVar('SDK_LOCAL_CONF_BLACKLIST', True) or '').split() |
| 122 | def handle_var(varname, origvalue, op, newlines): |
| 123 | if varname in local_conf_blacklist or (origvalue.strip().startswith('/') and not varname in local_conf_whitelist): |
| 124 | newlines.append('# Removed original setting of %s\n' % varname) |
| 125 | return None, op, 0, True |
| 126 | else: |
| 127 | return origvalue, op, 0, True |
| 128 | varlist = ['[^#=+ ]*'] |
| 129 | builddir = d.getVar('TOPDIR', True) |
| 130 | with open(builddir + '/conf/local.conf', 'r') as f: |
| 131 | oldlines = f.readlines() |
| 132 | (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var) |
| 133 | |
| 134 | with open(baseoutpath + '/conf/local.conf', 'w') as f: |
| 135 | f.write('# WARNING: this configuration has been automatically generated and in\n') |
| 136 | f.write('# most cases should not be edited. If you need more flexibility than\n') |
| 137 | f.write('# this configuration provides, it is strongly suggested that you set\n') |
| 138 | f.write('# up a proper instance of the full build system and use that instead.\n\n') |
| 139 | for line in newlines: |
| 140 | if line.strip() and not line.startswith('#'): |
| 141 | f.write(line) |
| 142 | |
| 143 | f.write('INHERIT += "%s"\n\n' % 'uninative') |
| 144 | f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False)) |
| 145 | |
| 146 | # Some classes are not suitable for SDK, remove them from INHERIT |
| 147 | f.write('INHERIT_remove = "%s"\n' % d.getVar('SDK_INHERIT_BLACKLIST')) |
| 148 | |
| 149 | # Bypass the default connectivity check if any |
| 150 | f.write('CONNECTIVITY_CHECK_URIS = ""\n\n') |
| 151 | |
| 152 | # Another hack, but we want the native part of sstate to be kept the same |
| 153 | # regardless of the host distro |
| 154 | fixedlsbstring = 'SDK-Fixed' |
| 155 | f.write('NATIVELSBSTRING_forcevariable = "%s"\n\n' % fixedlsbstring) |
| 156 | |
| 157 | # Ensure locked sstate cache objects are re-used without error |
| 158 | f.write('SIGGEN_LOCKEDSIGS_CHECK_LEVEL = "warn"\n\n') |
| 159 | |
| 160 | f.write('require conf/locked-sigs.inc\n') |
| 161 | f.write('require conf/work-config.inc\n') |
| 162 | |
| 163 | sigfile = d.getVar('WORKDIR', True) + '/locked-sigs.inc' |
| 164 | oe.copy_buildsystem.generate_locked_sigs(sigfile, d) |
| 165 | |
| 166 | # Filter the locked signatures file to just the sstate tasks we are interested in |
| 167 | allowed_tasks = ['do_populate_lic', 'do_populate_sysroot', 'do_packagedata', 'do_package_write_ipk', 'do_package_write_rpm', 'do_package_write_deb', 'do_package_qa', 'do_deploy'] |
| 168 | excluded_targets = d.getVar('SDK_TARGETS', True) |
| 169 | lockedsigs_pruned = baseoutpath + '/conf/locked-sigs.inc' |
| 170 | oe.copy_buildsystem.prune_lockedsigs(allowed_tasks, |
| 171 | excluded_targets, |
| 172 | sigfile, |
| 173 | lockedsigs_pruned) |
| 174 | |
| 175 | sstate_out = baseoutpath + '/sstate-cache' |
| 176 | bb.utils.remove(sstate_out, True) |
| 177 | oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned, |
| 178 | d.getVar('SSTATE_DIR', True), |
| 179 | sstate_out, d, |
| 180 | fixedlsbstring) |
| 181 | |
| 182 | # Create a dummy config file for additional settings |
| 183 | with open(baseoutpath + '/conf/work-config.inc', 'w') as f: |
| 184 | pass |
| 185 | } |
| 186 | |
| 187 | def extsdk_get_buildtools_filename(d): |
| 188 | # This is somewhat of a hack |
| 189 | localdata = bb.data.createCopy(d) |
| 190 | localdata.setVar('PN', 'buildtools-tarball') |
| 191 | return localdata.expand('${SDK_NAME}-buildtools-nativesdk-standalone-*.sh') |
| 192 | |
| 193 | install_tools() { |
| 194 | install -d ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk} |
| 195 | lnr ${SDK_OUTPUT}/${SDKPATH}/${scriptrelpath}/devtool ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/devtool |
| 196 | lnr ${SDK_OUTPUT}/${SDKPATH}/${scriptrelpath}/recipetool ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/recipetool |
| 197 | touch ${SDK_OUTPUT}/${SDKPATH}/.devtoolbase |
| 198 | |
| 199 | # find latest buildtools-tarball and install it |
| 200 | buildtools_path=`ls -t1 ${SDK_DEPLOY}/${@extsdk_get_buildtools_filename(d)} | head -n1` |
| 201 | install $buildtools_path ${SDK_OUTPUT}/${SDKPATH} |
| 202 | |
| 203 | install ${SDK_DEPLOY}/${BUILD_ARCH}-nativesdk-libc.tar.bz2 ${SDK_OUTPUT}/${SDKPATH} |
| 204 | } |
| 205 | |
| 206 | # Since bitbake won't run as root it doesn't make sense to try and install |
| 207 | # the extensible sdk as root. |
| 208 | sdk_ext_preinst() { |
| 209 | if [ "`id -u`" = "0" ]; then |
| 210 | echo "ERROR: The extensible sdk cannot be installed as root." |
| 211 | exit 1 |
| 212 | fi |
| 213 | SDK_EXTENSIBLE="1" |
| 214 | } |
| 215 | SDK_PRE_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_preinst}" |
| 216 | |
| 217 | # FIXME this preparation should be done as part of the SDK construction |
| 218 | sdk_ext_postinst() { |
| 219 | printf "\nExtracting buildtools...\n" |
| 220 | cd $target_sdk_dir |
| 221 | printf "buildtools\ny" | ./*buildtools-nativesdk-standalone* > /dev/null |
| 222 | |
| 223 | # Make sure when the user sets up the environment, they also get |
| 224 | # the buildtools-tarball tools in their path. |
| 225 | echo ". $target_sdk_dir/buildtools/environment-setup*" >> $target_sdk_dir/environment-setup* |
| 226 | |
| 227 | # Allow bitbake environment setup to be ran as part of this sdk. |
| 228 | echo "export OE_SKIP_SDK_CHECK=1" >> $target_sdk_dir/environment-setup* |
| 229 | |
| 230 | # A bit of another hack, but we need this in the path only for devtool |
| 231 | # so put it at the end of $PATH. |
| 232 | echo "export PATH=\$PATH:$target_sdk_dir/sysroots/${SDK_SYS}/${bindir_nativesdk}" >> $target_sdk_dir/environment-setup* |
| 233 | |
| 234 | # For now this is where uninative.bbclass expects the tarball |
| 235 | mv *-nativesdk-libc.tar.* $target_sdk_dir/`dirname ${oe_init_build_env_path}` |
| 236 | |
| 237 | if [ "$prepare_buildsystem" != "no" ]; then |
| 238 | printf "Preparing build system...\n" |
| 239 | # dash which is /bin/sh on Ubuntu will not preserve the |
| 240 | # current working directory when first ran, nor will it set $1 when |
| 241 | # sourcing a script. That is why this has to look so ugly. |
| 242 | sh -c ". buildtools/environment-setup* > preparing_build_system.log && cd $target_sdk_dir/`dirname ${oe_init_build_env_path}` && set $target_sdk_dir && . $target_sdk_dir/${oe_init_build_env_path} $target_sdk_dir >> preparing_build_system.log && bitbake ${SDK_TARGETS} >> preparing_build_system.log" || { echo "SDK preparation failed: see `pwd`/preparing_build_system.log" ; exit 1 ; } |
| 243 | fi |
| 244 | echo done |
| 245 | } |
| 246 | |
| 247 | SDK_POST_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_postinst}" |
| 248 | |
| 249 | SDK_POSTPROCESS_COMMAND_prepend_task-populate-sdk-ext = "copy_buildsystem; install_tools; " |
| 250 | |
| 251 | fakeroot python do_populate_sdk_ext() { |
| 252 | bb.build.exec_func("do_populate_sdk", d) |
| 253 | } |
| 254 | |
| 255 | def get_sdk_ext_rdepends(d): |
| 256 | localdata = d.createCopy() |
| 257 | localdata.appendVar('OVERRIDES', ':task-populate-sdk-ext') |
| 258 | bb.data.update_data(localdata) |
| 259 | return localdata.getVarFlag('do_populate_sdk', 'rdepends', True) |
| 260 | |
| 261 | do_populate_sdk_ext[dirs] = "${@d.getVarFlag('do_populate_sdk', 'dirs', False)}" |
| 262 | do_populate_sdk_ext[depends] += "${@d.getVarFlag('do_populate_sdk', 'depends', False)}" |
| 263 | do_populate_sdk_ext[rdepends] = "${@get_sdk_ext_rdepends(d)}" |
| 264 | do_populate_sdk_ext[recrdeptask] += "${@d.getVarFlag('do_populate_sdk', 'recrdeptask', False)}" |
| 265 | |
| 266 | |
| 267 | do_populate_sdk_ext[depends] += "buildtools-tarball:do_populate_sdk uninative-tarball:do_populate_sdk" |
| 268 | |
| 269 | do_populate_sdk_ext[rdepends] += "${@' '.join([x + ':do_build' for x in d.getVar('SDK_TARGETS', True).split()])}" |
| 270 | do_populate_sdk_ext[recrdeptask] += "do_populate_lic do_package_qa do_populate_sysroot do_deploy" |
| 271 | |
| 272 | # Make sure codes change in copy_buildsystem can result in rebuilt |
| 273 | do_populate_sdk_ext[vardeps] += "copy_buildsystem" |
| 274 | |
| 275 | addtask populate_sdk_ext |