From: Andrew Tridgell Date: Thu, 1 Apr 2010 11:19:32 +0000 (+1100) Subject: build: much simpler and faster rpath install handler X-Git-Tag: samba-3.6.0pre1~3297 X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=ba64e236d59619cb4222225ac98efe2a2c07f592;p=nivanova%2Fsamba-autobuild%2F.git build: much simpler and faster rpath install handler This avoids creating additional task generators at build time, and instead moves all the rpath logic into samba_install.py where it is triggered by the install_lib and install_bin features --- diff --git a/buildtools/wafsamba/samba_deps.py b/buildtools/wafsamba/samba_deps.py index 3c5c327c1d4..a05092f525b 100644 --- a/buildtools/wafsamba/samba_deps.py +++ b/buildtools/wafsamba/samba_deps.py @@ -310,13 +310,6 @@ def add_samba_attributes(bld, tgt_list): t.samba_deps_extended = t.samba_deps[:] t.samba_includes_extended = TO_LIST(t.samba_includes)[:] t.ccflags = getattr(t, 'samba_cflags', '') - install_target = getattr(t, 'install_target', None) - if Options.is_install and install_target: - t2 = bld.name_to_obj(install_target, bld.env) - t2.sname = install_target - t2.samba_type = t.samba_type - t2.samba_abspath = t2.path.abspath(bld.env) - t2.ccflags = t.ccflags def build_direct_deps(bld, tgt_list): @@ -784,23 +777,15 @@ def load_samba_deps(bld, tgt_list): #print '%s: \ntdeps=%s \nodeps=%s' % (t.sname, tdeps, olddeps) return False - tgt_list_extended = tgt_list[:] - if Options.is_install: - for t in tgt_list: - install_target = getattr(t, 'install_target', None) - if install_target: - t2 = bld.name_to_obj(install_target, bld.env) - tgt_list_extended.append(t2) - # put outputs in place - for t in tgt_list_extended: + for t in tgt_list: if not t.sname in denv.output: continue tdeps = denv.output[t.sname] for a in tdeps: setattr(t, a, tdeps[a]) # put output env vars in place - for t in tgt_list_extended: + for t in tgt_list: if not t.sname in denv.outenv: continue tdeps = denv.outenv[t.sname] for a in tdeps: @@ -811,32 +796,6 @@ def load_samba_deps(bld, tgt_list): -def add_install_deps(bld, tgt_list): - '''add attributes for install libs/binaries - - This ensures that all the install targets have identical dependencies - to the build targets. - ''' - if not Options.is_install: - return - - for t in tgt_list[:]: - install_target = getattr(t, 'install_target', None) - if install_target: - t2 = bld.name_to_obj(install_target, bld.env) - if not t2: - print('install_target %s not found for %s' % (install_target, t.sname)) - sys.exit(1) - tgt_list.append(t2) - for attr in savedeps_outputs: - v = getattr(t, attr, None) - if v: - setattr(t2, attr, v) - for attr in savedeps_outenv: - if attr in t.env: - t2.env[attr] = t.env[attr] - - def check_project_rules(bld): '''check the project rules - ensuring the targets are sane''' @@ -847,8 +806,6 @@ def check_project_rules(bld): # build a list of task generators we are interested in tgt_list = [] for tgt in targets: - if tgt.endswith('.inst'): - continue type = targets[tgt] if not type in ['SUBSYSTEM', 'MODULE', 'BINARY', 'LIBRARY', 'ASN1', 'PYTHON']: continue @@ -861,7 +818,6 @@ def check_project_rules(bld): add_samba_attributes(bld, tgt_list) if load_samba_deps(bld, tgt_list): - add_install_deps(bld, tgt_list) return print "Checking project rules ..." @@ -893,8 +849,6 @@ def check_project_rules(bld): save_samba_deps(bld, tgt_list) - add_install_deps(bld, tgt_list) - print "Project rules pass" diff --git a/buildtools/wafsamba/samba_install.py b/buildtools/wafsamba/samba_install.py new file mode 100644 index 00000000000..71d6b86122f --- /dev/null +++ b/buildtools/wafsamba/samba_install.py @@ -0,0 +1,158 @@ +########################### +# this handles the magic we need to do for installing +# with all the configure options that affect rpath and shared +# library use + +import Options +from TaskGen import feature, before, after +from samba_utils import * + +@feature('install_bin') +@after('apply_core') +@before('apply_link') +def install_binary(self): + '''install a binary, taking account of the different rpath varients''' + bld = self.bld + + # get the ldflags we will use for install and build + install_ldflags = install_rpath(bld) + build_ldflags = build_rpath(bld) + + if not Options.is_install or not self.samba_install: + # just need to set rpath if we are not installing + self.env.append_value('LINKFLAGS', build_ldflags) + return + + # work out the install path, expanding variables + install_path = self.samba_inst_path or '${BINDIR}' + install_path = bld.EXPAND_VARIABLES(install_path) + + orig_target = self.target + + if install_ldflags != build_ldflags: + # we will be creating a new target name, and using that for the + # install link. That stops us from overwriting the existing build + # target, which has different ldflags + self.target += '.inst' + + # setup the right rpath link flags for the install + self.env.append_value('LINKFLAGS', install_ldflags) + + # tell waf to install the right binary + bld.install_as(os.path.join(install_path, orig_target), + os.path.join(self.path.abspath(bld.env), self.target), + chmod=0755) + + + +@feature('install_lib') +@after('apply_core') +@before('apply_link') +def install_library(self): + '''install a library, taking account of the different rpath varients''' + if getattr(self, 'done_install_library', False): + return + + bld = self.bld + + install_ldflags = install_rpath(bld) + build_ldflags = build_rpath(bld) + + if not Options.is_install or not self.samba_install: + # just need to set the build rpath if we are not installing + self.env.append_value('LINKFLAGS', build_ldflags) + return + + # setup the install path, expanding variables + install_path = self.samba_inst_path or '${LIBDIR}' + install_path = bld.EXPAND_VARIABLES(install_path) + + if install_ldflags != build_ldflags: + # we will be creating a new target name, and using that for the + # install link. That stops us from overwriting the existing build + # target, which has different ldflags + self.done_install_library = True + t = self.clone('default') + t.target += '.inst' + self.env.append_value('LINKFLAGS', build_ldflags) + else: + t = self + + t.env.append_value('LINKFLAGS', install_ldflags) + + if self.samba_realname: + install_name = self.samba_realname + install_link = None + inst_name = t.target + '.so' + elif self.vnum: + vnum_base = self.vnum.split('.')[0] + install_name = 'lib%s.so.%s' % (self.target, self.vnum) + install_link = 'lib%s.so.%s' % (self.target, vnum_base) + inst_name = 'lib%s.so' % t.target + else: + install_name = 'lib%s.so' % self.target + install_link = None + inst_name = 'lib%s.so' % t.target + + # tell waf to install the library + bld.install_as(os.path.join(install_path, install_name), + os.path.join(self.path.abspath(bld.env), inst_name)) + if install_link: + # and the symlink if needed + bld.symlink_as(os.path.join(install_path, install_link), + install_name) + + + +############################## +# handle the creation of links for libraries and binaries in the build tree +# note that we use a relative symlink path to allow the whole tree +# to me moved/copied elsewhere without breaking the links +t = Task.simple_task_type('symlink_lib', 'rm -f ${LINK_TARGET} && ln -s ${LINK_SOURCE} ${LINK_TARGET}', + shell=True, color='PINK', ext_in='.bin') +t.quiet = True + +@feature('symlink_lib') +@after('apply_link') +def symlink_lib(self): + '''symlink a shared lib''' + if Options.is_install: + return + + tsk = self.create_task('symlink_lib', self.link_task.outputs[0]) + + # calculat the link target and put it in the environment + soext="" + vnum = getattr(self, 'vnum', None) + if vnum is not None: + soext = '.' + vnum.split('.')[0] + + link_target = getattr(self, 'link_name', '') + if link_target == '': + link_target = '%s/lib%s.so%s' % (LIB_PATH, self.target, soext) + + + link_source = os_path_relpath(self.link_task.outputs[0].abspath(self.env), + os.path.join(self.env.BUILD_DIRECTORY, link_target)) + + tsk.env.LINK_TARGET = link_target + tsk.env.LINK_SOURCE = link_source[3:] + debug('task_gen: LINK for %s is %s -> %s', + self.name, tsk.env.LINK_SOURCE, tsk.env.LINK_TARGET) + + +t = Task.simple_task_type('symlink_bin', 'rm -f ${BIN_TARGET} && ln -s ${SRC} ${BIN_TARGET}', + shell=True, color='PINK', ext_in='.bin') +t.quiet = True + +@feature('symlink_bin') +@after('apply_link') +def symlink_bin(self): + '''symlink a binary''' + if Options.is_install: + return + tsk = self.create_task('symlink_bin', self.link_task.outputs[0]) + + tsk.env.BIN_TARGET = self.target + debug('task_gen: BIN_TARGET for %s is %s', self.name, tsk.env.BIN_TARGET) + diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py index ecb044b5a1c..4658c59aeb6 100644 --- a/buildtools/wafsamba/wafsamba.py +++ b/buildtools/wafsamba/wafsamba.py @@ -18,6 +18,7 @@ from samba_autoproto import * from samba_python import * from samba_deps import * from samba_bundled import * +import samba_install import samba_conftests # some systems have broken threading in python @@ -142,7 +143,7 @@ def SAMBA_LIBRARY(bld, libname, source, else: bundled_name = BUNDLED_NAME(bld, libname, bundled_extension) - features = 'cc cshlib' + features = 'cc cshlib symlink_lib install_lib' if target_type == 'PYTHON': features += ' pyext' elif needs_python: @@ -150,7 +151,7 @@ def SAMBA_LIBRARY(bld, libname, source, bld.SET_BUILD_GROUP(group) t = bld( - features = features + ' symlink_lib', + features = features, source = [], target = bundled_name, samba_cflags = CURRENT_CFLAGS(bld, libname, cflags), @@ -160,63 +161,15 @@ def SAMBA_LIBRARY(bld, libname, source, local_include = local_include, vnum = vnum, install_path = None, - ldflags = build_rpath(bld), - name = libname + samba_inst_path = install_path, + name = libname, + samba_realname = realname, + samba_install = install ) if link_name: t.link_name = link_name - # we don't need the double libraries if rpath is off - if (bld.env.RPATH_ON_INSTALL == False and - bld.env.RPATH_ON_BUILD == False): - install_target = bundled_name - else: - install_target = bundled_name + '.inst' - if install: - t.install_target = install_target - - if install_path is None: - install_path = '${LIBDIR}' - install_path = SUBST_VARS_RECURSIVE(install_path, bld.env) - - if Options.is_install and install and install_target != bundled_name: - # create a separate install library, which may have - # different rpath settings - t = bld( - features = features, - source = [], - target = install_target, - samba_cflags = CURRENT_CFLAGS(bld, libname, cflags), - depends_on = depends_on, - samba_deps = deps, - samba_includes = includes, - local_include = local_include, - vnum = vnum, - install_as = bundled_name, - install_path = None, - ldflags = install_rpath(bld) - ) - - if Options.is_install and install: - if realname: - install_name = realname - install_link = None - inst_name = install_target + '.so' - elif vnum: - vnum_base = vnum.split('.')[0] - install_name = 'lib%s.so.%s' % (bundled_name, vnum) - install_link = 'lib%s.so.%s' % (bundled_name, vnum_base) - inst_name = 'lib%s.so' % install_target - else: - install_name = 'lib%s.so' % bundled_name - install_link = None - inst_name = 'lib%s.so' % install_target - - bld.install_as(os.path.join(install_path, install_name), inst_name) - if install_link: - bld.symlink_as(os.path.join(install_path, install_link), install_name) - if autoproto is not None: bld.SAMBA_AUTOPROTO(autoproto, source) @@ -255,7 +208,7 @@ def SAMBA_BINARY(bld, binname, source, if not SET_TARGET_TYPE(bld, binname, 'BINARY'): return - features = 'cc cprogram' + features = 'cc cprogram symlink_bin install_bin' if needs_python: features += ' pyembed' @@ -279,12 +232,12 @@ def SAMBA_BINARY(bld, binname, source, bld.SET_BUILD_GROUP(group) - # the library itself will depend on that object target + # the binary itself will depend on that object target deps = TO_LIST(deps) deps.append(obj_target) t = bld( - features = features + ' symlink_bin', + features = features, source = [], target = binname, samba_cflags = CURRENT_CFLAGS(bld, binname, cflags), @@ -295,45 +248,10 @@ def SAMBA_BINARY(bld, binname, source, top = True, samba_subsystem= subsystem_name, install_path = None, - ldflags = build_rpath(bld) + samba_inst_path= install_path, + samba_install = install ) - if install_path is None: - install_path = '${BINDIR}' - install_path = SUBST_VARS_RECURSIVE(install_path, bld.env) - - # we don't need the double binaries if rpath is off - if (bld.env.RPATH_ON_INSTALL == False and - bld.env.RPATH_ON_BUILD == False): - install_target = binname - else: - install_target = binname + '.inst' - if install: - t.install_target = install_target - - if Options.is_install and install and install_target != binname: - # we create a separate 'install' binary, which - # will have different rpath settings - t = bld( - features = features, - source = [], - target = install_target, - samba_cflags = CURRENT_CFLAGS(bld, binname, cflags), - samba_deps = deps, - samba_includes = includes, - local_include = local_include, - samba_modules = modules, - top = True, - samba_subsystem= subsystem_name, - install_path = None, - ldflags = install_rpath(bld) - ) - - if Options.is_install and install: - bld.install_as(os.path.join(install_path, binname), - install_target, - chmod=0755) - # setup the subsystem_name as an alias for the real # binary name, so it can be found when expanding # subsystem dependencies @@ -581,62 +499,6 @@ def ENABLE_TIMESTAMP_DEPENDENCIES(conf): -############################## -# handle the creation of links for libraries and binaries -# note that we use a relative symlink path to allow the whole tree -# to me moved/copied elsewhere without breaking the links -t = Task.simple_task_type('symlink_lib', 'rm -f ${LINK_TARGET} && ln -s ${LINK_SOURCE} ${LINK_TARGET}', - shell=True, color='PINK', ext_in='.bin') -t.quiet = True - -@feature('symlink_lib') -@after('apply_link') -def symlink_lib(self): - '''symlink a shared lib''' - tsk = self.create_task('symlink_lib', self.link_task.outputs[0]) - - # calculat the link target and put it in the environment - soext="" - vnum = getattr(self, 'vnum', None) - if vnum is not None: - soext = '.' + vnum.split('.')[0] - - link_target = getattr(self, 'link_name', '') - if link_target == '': - link_target = '%s/lib%s.so%s' % (LIB_PATH, self.target, soext) - - - link_source = os_path_relpath(self.link_task.outputs[0].abspath(self.env), - os.path.join(self.env.BUILD_DIRECTORY, link_target)) - - tsk.env.LINK_TARGET = link_target - tsk.env.LINK_SOURCE = link_source[3:] - debug('task_gen: LINK for %s is %s -> %s', - self.name, tsk.env.LINK_SOURCE, tsk.env.LINK_TARGET) - - -t = Task.simple_task_type('symlink_bin', 'rm -f ${BIN_TARGET} && ln -s ${SRC} ${BIN_TARGET}', - shell=True, color='PINK', ext_in='.bin') -t.quiet = True - -@feature('symlink_bin') -@after('apply_link') -def symlink_bin(self): - '''symlink a binary''' - if Options.is_install: - # we don't want to copy the install binary, as - # that has the install rpath, not the build rpath - # The rpath of the binaries in bin/default/foo/blah is different - # during the install phase, as distros insist on not using rpath in installed binaries - return - tsk = self.create_task('symlink_bin', self.link_task.outputs[0]) - - tsk.env.BIN_TARGET = self.target - debug('task_gen: BIN_TARGET for %s is %s', self.name, tsk.env.BIN_TARGET) - - - - t = Task.simple_task_type('copy_script', 'rm -f ${LINK_TARGET} && ln -s ${SRC[0].abspath(env)} ${LINK_TARGET}', shell=True, color='PINK', ext_in='.bin') t.quiet = True