This big hammer makes Samba4 binaries usable (again). Tested successfully on i386. Unless someone objects, or come with better solution, I'll commit this at the next evening.
-- WBR, Vadim Zhukov Index: patches/patch-buildtools_wafadmin_Tools_cc_py =================================================================== RCS file: patches/patch-buildtools_wafadmin_Tools_cc_py diff -N patches/patch-buildtools_wafadmin_Tools_cc_py --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-buildtools_wafadmin_Tools_cc_py 22 May 2014 18:39:34 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +Reorder object files to minimize library interrefs count. +Speeds up loading of library files. +--- buildtools/wafadmin/Tools/cc.py.orig Mon May 19 17:29:02 2014 ++++ buildtools/wafadmin/Tools/cc.py Mon May 19 18:05:26 2014 +@@ -93,8 +93,8 @@ cls = Task.simple_task_type('cc', cc_str, 'GREEN', ext + cls.scan = ccroot.scan + cls.vars.append('CCDEPS') + +-link_str = '${LINK_CC} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}' +-cls = Task.simple_task_type('cc_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False) ++link_str = '${LINK_CC} ${CCLNK_SRC_F} `set -- ${SRC}; test $# -gt 0 && lorder "$@" | tsort -q` ${CCLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}' ++cls = Task.simple_task_type('cc_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=True) + cls.maxjobs = 1 + cls.install = Utils.nada + Index: patches/patch-buildtools_wafadmin_Tools_ccroot_py =================================================================== RCS file: /cvs/ports/net/samba4/patches/patch-buildtools_wafadmin_Tools_ccroot_py,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 patch-buildtools_wafadmin_Tools_ccroot_py --- patches/patch-buildtools_wafadmin_Tools_ccroot_py 4 May 2014 16:08:29 -0000 1.1.1.1 +++ patches/patch-buildtools_wafadmin_Tools_ccroot_py 22 May 2014 18:39:34 -0000 @@ -1,9 +1,171 @@ $OpenBSD: patch-buildtools_wafadmin_Tools_ccroot_py,v 1.1.1.1 2014/05/04 16:08:29 zhuk Exp $ -Make Samba4 WAF respect OpenBSD shared libraries versioning conventions. -BUG: https://bugzilla.samba.org/show_bug.cgi?id=9774 ---- buildtools/wafadmin/Tools/ccroot.py.orig Mon May 27 17:48:53 2013 -+++ buildtools/wafadmin/Tools/ccroot.py Mon May 27 18:06:35 2013 -@@ -568,7 +568,7 @@ def apply_implib(self): +1. Make Samba4 WAF respect OpenBSD shared libraries versioning conventions. + BUG: https://bugzilla.samba.org/show_bug.cgi?id=9774 + +2. Speed up starting Samba binaries by a factor of 10 by reordering. + This adds debug printing "SCANNING" to give a clue that build is + still going. +libraries during linking. +--- buildtools/wafadmin/Tools/ccroot.py.orig Mon May 19 19:54:23 2014 ++++ buildtools/wafadmin/Tools/ccroot.py Thu May 22 22:28:51 2014 +@@ -4,7 +4,7 @@ + + "base for all c/c++ programs and libraries" + +-import os, sys, re ++import os, sys, re, stat, subprocess + import TaskGen, Task, Utils, preproc, Logs, Build, Options + from Logs import error, debug, warn + from Utils import md5 +@@ -19,6 +19,9 @@ except ImportError: + import config_c # <- necessary for the configuration, do not touch + + USE_TOP_LEVEL = False ++LIBFILES_CACHE = {} ++DIR_CACHE = {} ++NM_CACHE = {} + + def get_cc_version(conf, cc, gcc=False, icc=False): + +@@ -450,6 +453,15 @@ def apply_objdeps(self): + for t in y.compiled_tasks: + self.link_task.inputs.extend(t.outputs) + ++def libver_key(file): ++ """generate sort key for library file path""" ++ v = re.search('\.so((\.[0-9]+)*)$', file).group(1).lstrip('.') ++ s = '' ++ for i in v.split('.'): ++ if len(i) > 0: ++ s = "%s.%04d" % (s, int(i)) ++ return s ++ + @feature('cprogram', 'cshlib', 'cstaticlib') + @after('apply_lib_vars') + def apply_obj_vars(self): +@@ -484,8 +496,120 @@ def apply_obj_vars(self): + if v['STATICLIB'] or v['LIB']: + v.append_value('LINKFLAGS', v['SHLIB_MARKER']) + +- app('LINKFLAGS', [lib_st % i for i in v['LIB']]) ++ libsleft = v['LIB'][:] ++ if sys.platform.startswith("openbsd"): ++ bldpath = self.bld.bldnode.abspath() ++ libdirs = [] ++ for i in v['LIBPATH']: ++ if i.startswith(bldpath) and not i in libdirs: ++ libdirs.append(i) ++ for i in v['LIBPATH']: ++ if not i.startswith(bldpath) and not i in libdirs: ++ libdirs.append(i) + ++ # Search for libraries and sort them using lorder(1), ++ # lowering number ld.so needs to load libraries in final ++ # binaries, and thus binaries start much faster. ++ libfiles = [] ++ for dir in libdirs: ++ if not os.path.isabs(dir): ++ dir = os.path.join(bldpath, dir) ++ ++ if dir in LIBFILES_CACHE: ++ dircache = LIBFILES_CACHE[dir] ++ newleft = libsleft ++ for lib in libsleft: ++ if lib in dircache: ++ libfiles.append(dircache[lib]) ++ newleft = [i for i in newleft if i != lib] ++ libsleft = newleft ++ if len(libsleft) == 0: ++ break ++ ++ if dir not in DIR_CACHE: ++ dirlibs = [] ++ for file in os.listdir(dir): ++ path = os.path.join(dir, file) ++ if not stat.S_ISREG(os.stat(path).st_mode): continue ++ if not re.match('(lib)?.*\.so(\.[0-9]+)*', file): continue ++ dirlibs.append(path) ++ DIR_CACHE[dir] = dirlibs ++ ++ ++ candidates = {} ++ newleft = libsleft ++ for path in DIR_CACHE[dir]: ++ for lib in libsleft: ++ if re.match('.*%s(lib)?%s\.so(\.[0-9]+)*' % (os.sep, lib), path): ++ if lib not in candidates: ++ candidates[lib] = [] ++ candidates[lib].append(path) ++ ++ # ++ # Avoid searching for libraries in future dirs. ++ # ++ # XXX Incorrect if called second time with ++ # additional directory containing given library ++ # and placed in list before other one, where ++ # the library given was found already. ++ # ++ newleft = [i for i in newleft if i != lib] ++ ++ libsleft = newleft ++ for lib in candidates.keys(): ++ bestpath = sorted(candidates[lib], key=libver_key).pop() ++ if not dir in LIBFILES_CACHE: ++ LIBFILES_CACHE[dir] = {} ++ LIBFILES_CACHE[dir][lib] = bestpath ++ libfiles.append(bestpath) ++ ++ if len(libfiles) > 0: ++ for f in libfiles: ++ if not f in NM_CACHE: ++ print "SCANNING %s" % f ++ exports = set() ++ refs = set() ++ out = subprocess.check_output(['nm', '-gop', '--', f]) ++ for l in out.splitlines(): ++ path, info = l.split(':', 2) ++ parts = info.split(None, 3) # addr, type, sym ++ if parts[0] == 'U': ++ refs.add(parts[1]) ++ elif 'TDGR'.find(parts[1]) != -1: ++ exports.add(parts[2]) ++ NM_CACHE[f] = (refs, exports) ++ ++ sortedfiles = [ libfiles.pop() ] ++ # print "BEGINNING WITH %s" % sortedfiles[0] ++ while len(libfiles) > 0: ++ f = libfiles.pop() ++ if f in sortedfiles: ++ # print "\tSKIPPING %s AS IT IS ALREADY THERE" % f ++ continue ++ # print "SEARCHING WHERE TO PLACE %s" % f ++ refs2, exports2 = NM_CACHE[f] ++ inspos = None ++ for i in range(len(sortedfiles)): ++ # print "\t\tCOMPARING WITH %s" % sortedfiles[i] ++ refs1, exports1 = NM_CACHE[sortedfiles[i]] ++ for r in refs2: ++ if r in exports1: ++ # print "%s DEPENDS ON %s" % (f, sortedfiles[i]) ++ inspos = i ++ break ++ if inspos is not None: ++ break ++ if inspos is None: ++ # print "%s WILL BE ADDED TO THE END" % f ++ inspos = len(sortedfiles) ++ sortedfiles.insert(inspos, f) ++ ++ app('LINKFLAGS', sortedfiles) ++ ++ if len(libsleft) > 0: ++ print "APPENDING LIBS: %s" % libsleft ++ app('LINKFLAGS', [lib_st % i for i in libsleft]) ++ + @after('apply_link') + def process_obj_files(self): + if not hasattr(self, 'obj_files'): return +@@ -568,7 +692,7 @@ def apply_implib(self): @before('apply_lib_vars', 'default_link_install') def apply_vnum(self): """ @@ -12,7 +174,7 @@ BUG: https://bugzilla.samba.org/show_bug """ if not getattr(self, 'vnum', '') or not 'cshlib' in self.features or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): return -@@ -576,19 +576,33 @@ def apply_vnum(self): +@@ -576,19 +700,33 @@ def apply_vnum(self): self.meths.remove('default_link_install') link = self.link_task @@ -51,7 +213,7 @@ BUG: https://bugzilla.samba.org/show_bug self.env.append_value('LINKFLAGS', v.split()) bld = self.bld -@@ -598,11 +612,11 @@ def apply_vnum(self): +@@ -598,11 +736,11 @@ def apply_vnum(self): if not path: return bld.install_as(path + os.sep + name3, node, env=self.env) Index: patches/patch-buildtools_wafadmin_Tools_cxx_py =================================================================== RCS file: patches/patch-buildtools_wafadmin_Tools_cxx_py diff -N patches/patch-buildtools_wafadmin_Tools_cxx_py --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-buildtools_wafadmin_Tools_cxx_py 22 May 2014 18:39:34 -0000 @@ -0,0 +1,14 @@ +$OpenBSD$ +Reorder object files to minimize library interrefs count. +Speeds up loading of library files. +--- buildtools/wafadmin/Tools/cxx.py.orig Mon May 19 18:30:35 2014 ++++ buildtools/wafadmin/Tools/cxx.py Mon May 19 18:31:28 2014 +@@ -97,7 +97,7 @@ cls = Task.simple_task_type('cxx', cxx_str, color='GRE + cls.scan = ccroot.scan + cls.vars.append('CXXDEPS') + +-link_str = '${LINK_CXX} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}' ++link_str = '${LINK_CXX} ${CXXLNK_SRC_F} `set -- ${SRC}; test $# -gt 0 && lorder "$@" | tsort -q` ${CXXLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}' + cls = Task.simple_task_type('cxx_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False) + cls.maxjobs = 1 + cls.install = Utils.nada