-rwxr-xr-x 24573 lib25519-20220426/configure raw
#!/usr/bin/env python3 import os import shutil import sys import platform import subprocess import tempfile import re prefix = '/usr/local' clean = True host = platform.machine() host = ''.join(c for c in host if c in '_0123456789abcdefghijklmnopqrstuvwxyz') def dirlinksym(dir,source,target): with tempfile.TemporaryDirectory(dir=dir) as t: os.symlink(target,'%s/symlink' % t) os.rename('%s/symlink' % t,'%s/%s' % (dir,source)) makefile = '' librandombytes = 'randombytes_kernel' libcpucycles = 'cpucycles' linktype = 'so' for arg in sys.argv[1:]: if arg.startswith('--prefix='): prefix = arg[9:] continue if arg.startswith('--host='): host = arg[8:] host = host.split('-')[0] continue if arg == '--clean': clean = True continue if arg == '--noclean': clean = False continue if arg == '--staticbinaries': linktype = 'a' # binaries usable by themselves continue if arg == '--nostaticbinaries': linktype = 'so' # save disk space continue raise ValueError('unrecognized argument %s' % arg) if host == 'x86_64': host = 'amd64' if host == 'i686': host = 'x86' if host == 'armv7': host = 'arm' echoargs = './configure' echoargs += ' --prefix=%s' % prefix echoargs += ' --host=%s' % host if clean: echoargs += ' --clean' if not clean: echoargs += ' --noclean' if linktype == 'a': echoargs += ' --staticbinaries' if linktype == 'so': echoargs += ' --nostaticbinaries' print(echoargs) if prefix[0] != '/': raise ValueError('prefix %s is not an absolute path' % prefix) rpath = None # XXX: rpath = '%s/lib' % prefix if clean: shutil.rmtree('build/%s' % host,ignore_errors=True) os.makedirs('build/%s' % host,exist_ok=True) os.makedirs('build/%s/package/bin' % host,exist_ok=True) os.makedirs('build/%s/package/lib' % host,exist_ok=True) os.makedirs('build/%s/package/include' % host,exist_ok=True) def copytree(src,dst): # starting with python 3.8 can use shutil.copytree # with dirs_exist_ok=True # but want to support older versions of python too os.makedirs(dst,exist_ok=True) for fn in sorted(os.listdir(src)): srcfn = '%s/%s' % (src,fn) dstfn = '%s/%s' % (dst,fn) if os.path.isdir(srcfn): copytree(srcfn,dstfn) else: shutil.copy2(srcfn,dstfn) shutil.copystat(src,dst) shutil.copy2('api','build/%s/api' % host) copytree('scripts-build','build/%s/scripts' % host) copytree('cpuid','build/%s/cpuid' % host) copytree('priority','build/%s/priority' % host) os.makedirs('build/%s/include-build' % host,exist_ok=True) shutil.copy2('randombytes/randombytes.h','build/%s/include-build/randombytes.h' % host) shutil.copy2('cpucycles/cpucycles.h','build/%s/include-build/cpucycles.h' % host) for bits in 8,16,32,64: with open('build/%s/include-build/crypto_int%d.h' % (host,bits),'w') as f: f.write('#include <inttypes.h>\n') f.write('#define crypto_int%d int%d_t' % (bits,bits)) with open('build/%s/include-build/crypto_uint%d.h' % (host,bits),'w') as f: f.write('#include <inttypes.h>\n') f.write('#define crypto_uint%d uint%d_t' % (bits,bits)) # ----- compilers def compilerversion(c): try: p = subprocess.Popen(c.split()+['--version'],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True) out,err = p.communicate() assert not err assert not p.returncode return out except: pass compilerversionline = {} compilers = {} for arch in sorted(os.listdir('compilers')): if arch.endswith('.c'): continue if arch == 'default' or arch == host or arch.startswith('%s+' % host): with open('compilers/%s' % arch) as f: for c in f.readlines(): c = c.strip() cv = compilerversion(c) if cv == None: print('skipping %s compiler %s' % (arch,c)) continue if arch not in compilers: compilers[arch] = [] compilers[arch] += [c] cv = (c+'\n'+cv).strip().replace('\n','; ') compilerversionline[arch,c] = cv print('using %s compiler %s' % (arch,cv)) firstcompiler = compilers['default'][0] compilerabbrev = {} i = 0 for arch in sorted(compilers): for compiler in compilers[arch]: compilerabbrev[arch,compiler] = 'C%d'%i i += 1 print('abbreviating %s = %s %s' % (compilerabbrev[arch,compiler],arch,compiler)) os.makedirs('build/%s/compilerarch' % host,exist_ok=True) for arch,compiler in compilerabbrev: with open('build/%s/compilerarch/%s' % (host,compilerabbrev[arch,compiler]),'w') as f: f.write('%s\n' % arch) os.makedirs('build/%s/compilerversion' % host,exist_ok=True) for arch,compiler in compilerabbrev: with open('build/%s/compilerversion/%s' % (host,compilerabbrev[arch,compiler]),'w') as f: f.write('%s\n' % compilerversionline[arch,compiler]) with open('build/%s/scripts/compiledefault' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('dir="$1"; shift\n') f.write('base="$1"; shift\n') f.write('ext="$1"; shift\n') f.write('\n') f.write('cd "$dir" && \\\n') f.write('%s \\\n' % firstcompiler) f.write(' -fvisibility=hidden \\\n') f.write(' "$@" \\\n') f.write(' -c "$base.$ext"\n') os.chmod('build/%s/scripts/compiledefault' % host,0o755) # ----- run-time checks for whether host actually supports compiler copytree('compilers','build/%s/compilers' % host) for arch in sorted(compilers): if arch == 'default': continue assert os.path.exists('compilers/%s.c'%arch) arch_csymbol = ''.join(x if x in '0123456789abcdefghijklmnopqrstuvwxyz' else '_' for x in arch) M = '\n' M += 'compilers/%s.o: compilers/%s.c\n' % (arch,arch) M += '\tscripts/compiledefault compilers %s c -Dsupports=lib25519_supports_%s\n' % (arch,arch_csymbol) makefile = M + makefile M = '\n' M += 'compilers-all: %s\n' % ' '.join('compilers/%s.o'%arch for arch in sorted(compilers) if arch != 'default') M += '\ttouch compilers-all\n' makefile = M + makefile # ----- crypto operations = [] primitives = {} sizes = {} exports = {} prototypes = {} with open('api') as f: for line in f: line = line.strip() if line.startswith('crypto_'): line = line.split('/') assert len(line) == 2 o = line[0].split('_')[1] if o not in operations: operations += [o] p = line[1] primitives[o] = p continue if line.startswith('#define '): x = line.split(' ') x = x[1].split('_') assert len(x) == 3 assert x[0] == 'crypto' o = x[1] if o not in sizes: sizes[o] = '' sizes[o] += line+'\n' continue if line.endswith(');'): fun,args = line[:-2].split('(') rettype,fun = fun.split() fun = fun.split('_') o = fun[1] assert fun[0] == 'crypto' if o not in exports: exports[o] = [] exports[o] += ['_'.join(fun[1:])] if o not in prototypes: prototypes[o] = [] prototypes[o] += [(rettype,fun,args)] lib25519h = """\ #ifndef lib25519_h #define lib25519_h #ifdef __cplusplus extern "C" { #endif """ with open('version') as f: version = f.readlines()[0].strip() def cstring(x): return '"%s"' % x.replace('\\','\\\\').replace('"','\\"').replace('\n','\\n') lib25519h += '\n' lib25519h += '#define lib25519_version %s\n' % cstring(version) lib25519h += '#define lib25519_arch %s\n' % cstring(host) lib25519h += '\n' lib25519h += 'extern void lib25519_cpuid(unsigned int *,long long);\n' for o in operations: if len(sizes[o]) > 0: lib25519h += '\n' lib25519h += re.sub(' crypto_',' lib25519_',sizes[o]) for rettype,fun,args in prototypes[o]: shortfun = '_'.join(fun[1:]) lib25519h += '\n' lib25519h += 'extern %s lib25519_%s(%s);\n' % (rettype,shortfun,args) lib25519h += 'extern %s (*lib25519_dispatch_%s(long long))(%s);\n' % (rettype,shortfun,args) lib25519h += '\n' lib25519h += 'extern const char *lib25519_%s_implementation(void);\n' % o lib25519h += 'extern const char *lib25519_%s_compiler(void);\n' % o lib25519h += 'extern const char *lib25519_dispatch_%s_implementation(long long);\n' % o lib25519h += 'extern const char *lib25519_dispatch_%s_compiler(long long);\n' % o lib25519h += 'extern long long lib25519_numimpl_%s(void);\n' % o lib25519h += """ #ifdef __cplusplus } #endif #endif """ with open('build/%s/package/include/lib25519.h' % host,'w') as f: f.write(lib25519h) os.chmod('build/%s/package/include/lib25519.h' % host,0o644) for o in operations: cryptoh = '' cryptoh += '#ifndef crypto_%s_%s_h\n' % (o,primitives[o]) cryptoh += '#define crypto_%s_%s_h\n' % (o,primitives[o]) cryptoh += '\n' for rettype,fun,args in prototypes[o]: shortfun = '_'.join(fun[1:]) cryptoh += '#define crypto_%s_%s lib25519_%s\n' % (shortfun,primitives[o],shortfun) cryptoh += '\n' cryptoh += re.sub('crypto_%s_'%o,'crypto_%s_%s_'%(o,primitives[o]),sizes[o]) cryptoh += '\n' for rettype,fun,args in prototypes[o]: shortfun = '_'.join(fun[1:]) cryptoh += 'extern %s crypto_%s_%s(%s);\n' % (rettype,shortfun,primitives[o],args) cryptoh += '\n' cryptoh += '#endif\n' with open('build/%s/include-build/crypto_%s_%s.h' % (host,o,primitives[o]),'w') as f: f.write(cryptoh) ofiles = [] oicdirs = [] for o in operations: for i in sorted(os.listdir('crypto_%s/%s' % (o,primitives[o]))): impldir = 'crypto_%s/%s/%s' % (o,primitives[o],i) if not os.path.isdir(impldir): continue if os.stat(impldir).st_mode & 0o1000 == 0o1000: print('skipping sticky %s' % impldir) continue implarch = None if os.path.exists('%s/architectures' % impldir): with open('%s/architectures' % impldir) as f: for line in f: line = line.strip().split() if len(line) == 0: continue if line[0] != host: continue implarch = line else: implarch = [host] if implarch == None: continue assert implarch[0] == host for arch in compilers: if any(implarchreq not in arch.split('+')[1:] for implarchreq in implarch[1:]): continue for compiler in compilers[arch]: compilerdir = compilerabbrev[arch,compiler] namespace = 'lib25519_%s_%s_%s' % (o,i.replace('-','_'),compilerabbrev[arch,compiler]) oicdirs += ['%s/%s/%s' % (o,i,compilerdir)] builddir = 'build/%s/%s/%s/%s' % (host,o,i,compilerdir) os.makedirs(builddir,exist_ok=True) copytree(impldir,builddir) doth = '' doth += '#ifndef crypto_%s_h\n' % o doth += '#define crypto_%s_h\n' % o doth += '\n' for m in exports[o]: doth += '#define crypto_%s CRYPTO_NAMESPACE(%s)\n' % (m,m) doth += '\n' doth += sizes[o] doth += '\n' for rettype,fun,args in prototypes[o]: doth += 'extern %s %s(%s) __attribute__((visibility("default")));\n' % (rettype,'_'.join(fun),args) doth += '\n' doth += '#endif\n' with open('%s/crypto_%s.h' % (builddir,o),'w') as f: f.write(doth) with open('%s/compile' % builddir,'w') as f: f.write('#!/bin/sh\n') f.write('base="$1"; shift\n') f.write('ext="$1"; shift\n') f.write('if %s \\\n' % compiler) f.write(' -I ../../../include-build \\\n') f.write(' -fvisibility=hidden \\\n') f.write(' -D"CRYPTO_NAMESPACE(name)=%s_##name" \\\n' % namespace) f.write(' -D"_CRYPTO_NAMESPACE(name)=_%s_##name" \\\n' % namespace) f.write(' -c "$base.$ext"\n') f.write('then\n') f.write(' :\n') f.write('else\n') f.write(' case "$?" in\n') f.write(' 111)\n') f.write(' # maybe someday compilers can be convinced\n') f.write(' # to use exit code 111 for temporary failures\n') f.write(' exit 111\n') f.write(' ;;\n') f.write(' *)\n') f.write(' : > "$base.o"\n') f.write(' touch "$base.o.compilefailed"\n') f.write(' esac\n') f.write('fi\n') os.chmod('%s/compile' % builddir,0o755) for fn in sorted(os.listdir(builddir)): if fn.endswith('.c') or fn.endswith('.S'): base = fn[:-2] ext = fn[-1:] makefile += '\n' ofiles += ['%s/%s/%s/%s.o' % (o,i,compilerdir,base)] makefile += '%s/%s/%s/%s.o: %s/%s/%s/%s\n' % (o,i,compilerdir,base,o,i,compilerdir,fn) makefile += '\tcd %s/%s/%s && ./compile %s %s\n' % (o,i,compilerdir,base,ext) # ----- dispatch M = 'compiledimplementations: scripts/compiledimplementations \\\n' for ofile in ofiles: M += '%s \\\n' % ofile M += '\n' M += '\tscripts/compiledimplementations \\\n' for oicdir in oicdirs: M += '\t%s \\\n' % oicdir M += '\t> compiledimplementations\n' makefile = M + makefile for goal in 'auto','manual': os.makedirs('build/%s/dispatch-%s' % (host,goal),exist_ok=True) M = '' for o in operations: M += 'dispatch-%s/%s.c: scripts/dispatch compiledimplementations\n' % (goal,o) M += '\tscripts/dispatch %s %s %s < compiledimplementations > dispatch-%s/%s.c\n' % (goal,o,host,goal,o) M += '\n' makefile = M + makefile M = '' for o in operations: M += 'dispatch-%s/%s.o: dispatch-%s/%s.c\n' % (goal,o,goal,o) M += '\tscripts/compiledefault dispatch-%s %s c\n' % (goal,o) M += '\n' makefile = M + makefile M = 'dispatch-%s-all: \\\n' % goal for o in operations: M += 'dispatch-%s/%s.o \\\n' % (goal,o) M += '\n' M += '\ttouch dispatch-%s-all\n' % goal M += '\n' makefile = M + makefile # ----- lib25519 M = 'odirs: compiledimplementations\n' M += '\t( cat compiledimplementations; echo dispatch-auto; echo dispatch-manual; echo compilers; echo cpuid ) > odirs\n' M += '\n' makefile = M + makefile M = 'ofiles: scripts/ofiles scripts/checknamespace odirs compiledimplementations dispatch-auto-all dispatch-manual-all compilers-all cpuid-all\n' M += '\tscripts/ofiles < odirs\n' M += '\tscripts/checknamespace lib25519 < odirs\n' M += '\n' makefile = M + makefile with open('build/%s/scripts/staticlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('rm -f package/lib/lib25519.a\n') f.write('ar cr package/lib/lib25519.a ofiles/*.o\n') f.write('ranlib package/lib/lib25519.a || :\n') f.write('chmod 644 package/lib/lib25519.a\n') os.chmod('build/%s/scripts/staticlib' % host,0o755) M = 'package/lib/lib25519.a: scripts/staticlib ofiles\n' M += '\tscripts/staticlib\n' M += '\n' makefile = M + makefile with open('build/%s/scripts/sharedlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('%s -shared \\\n' % firstcompiler) if rpath: f.write(' -Wl,-rpath=%s \\\n' % rpath) f.write(' -Wl,-soname,lib25519.so.1 \\\n') f.write(' -o package/lib/lib25519.so.1 \\\n') f.write(' ofiles/*.o\n') f.write('chmod 644 package/lib/lib25519.so.1\n') os.chmod('build/%s/scripts/sharedlib' % host,0o755) M = 'package/lib/lib25519.so.1: scripts/sharedlib ofiles\n' M += '\tscripts/sharedlib\n' M += '\n' makefile = M + makefile M = 'package/lib/lib25519.so: package/lib/lib25519.so.1\n' M += '\trm -f package/lib/lib25519.so\n' M += '\tln -s lib25519.so.1 package/lib/lib25519.so\n' M += '\n' makefile = M + makefile # ----- librandombytes copytree('randombytes','build/%s/randombytes' % host) for r in 'devurandom',: M = 'randombytes/%s.o: randombytes/%s.c\n' % (r,r) M += '\tscripts/compiledefault randombytes %s c -I ../include-build\n' % r M += '\n' makefile = M + makefile with open('build/%s/randombytes/staticlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('rm -f package/lib/lib%s.a\n' % librandombytes) f.write('ar cr package/lib/lib%s.a randombytes/*.o\n' % librandombytes) f.write('ranlib package/lib/lib%s.a || :\n' % librandombytes) f.write('chmod 644 package/lib/lib%s.a\n' % librandombytes) os.chmod('build/%s/randombytes/staticlib' % host,0o755) M = 'package/lib/lib%s.a: randombytes/staticlib randombytes/devurandom.o\n' % librandombytes M += '\trandombytes/staticlib\n' M += '\n' makefile = M + makefile with open('build/%s/randombytes/sharedlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('%s -shared \\\n' % firstcompiler) if rpath: f.write(' -Wl,-rpath=%s \\\n' % rpath) f.write(' -Wl,-soname,lib%s.so.1 \\\n' % librandombytes) f.write(' -o package/lib/lib%s.so.1 \\\n' % librandombytes) f.write(' randombytes/devurandom.o\n') f.write('chmod 644 package/lib/lib%s.so.1\n' % librandombytes) os.chmod('build/%s/randombytes/sharedlib' % host,0o755) M = 'package/lib/lib%s.so.1: randombytes/sharedlib randombytes/devurandom.o\n' % librandombytes M += '\trandombytes/sharedlib\n' M += '\n' makefile = M + makefile M = 'package/lib/lib%s.so: package/lib/lib%s.so.1\n' % (librandombytes,librandombytes) M += '\trm -f package/lib/lib%s.so\n' % librandombytes M += '\tln -s lib%s.so.1 package/lib/lib%s.so\n' % (librandombytes,librandombytes) M += '\n' makefile = M + makefile # ----- cpuid cpuid = host if not os.path.exists('cpuid/%s.c' % host): cpuid = 'default' M = 'cpuid-all: cpuid/%s.o\n' % cpuid M += '\ttouch cpuid-all\n' M += '\n' M += 'cpuid/%s.o: cpuid/%s.c\n' % (cpuid,cpuid) M += '\tscripts/compiledefault cpuid %s c\n' % cpuid M += '\n' makefile += M # ----- libcpucycles os.makedirs('build/%s/cpucycles' % host,exist_ok=True) with open('build/%s/cpucycles/compile-ticks' % host,'w') as f: f.write('#!/bin/sh\n') f.write('arch="$1"; shift\n') f.write('x="$1"; shift\n') f.write('for source in try-"$arch"-"$x".c try-default-zero.c\n') f.write('do\n') f.write(' cp "$source" "$arch"-"$x".c\n') f.write(' %s \\\n' % firstcompiler) f.write(' -I ../include-build \\\n') f.write(' -fvisibility=hidden \\\n') f.write(' -Dticks=cpucycles_ticks_"$arch"_"$x" \\\n') f.write(' -Dticks_setup=cpucycles_ticks_"$arch"_"$x"_setup \\\n') f.write(' -c "$arch"-"$x".c\n') f.write(' case $? in\n') f.write(' 0) break ;;\n') f.write(' 111) exit 111 ;;\n') f.write(' esac\n') f.write('done\n') os.chmod('build/%s/cpucycles/compile-ticks' % host,0o755) cpucyclesoptions = [] cpucyclesofiles = [] with open('cpucycles/options') as f: for line in f: line = line.strip() if line == '': continue if line[0] == '#': continue base = line.split()[0] if not os.path.exists('cpucycles/%s.c' % base): continue cpucycles = base.split('-') if len(cpucycles) != 2: continue if cpucycles[0] not in (host,'default'): continue cpucyclesoptions += [cpucycles] cpucyclesoptions += [['default','zero']] # must be last for cpucycles in cpucyclesoptions: base = '-'.join(cpucycles) cpucyclesofiles += ['cpucycles/%s.o' % base] shutil.copy2('cpucycles/%s.c' % base,'build/%s/cpucycles/try-%s.c' % (host,base)) M = 'cpucycles/%s.o: cpucycles/try-%s.c cpucycles/try-default-zero.c\n' % (base,base) M += '\tcd cpucycles && ./compile-ticks %s %s\n' % (cpucycles[0],cpucycles[1]) M += '\n' makefile = M + makefile for fn in sorted(os.listdir('cpucycles')): if not fn.endswith('.c'): continue if '-' in fn: continue base = fn[:-2] cpucyclesofiles += ['cpucycles/%s.o' % base] shutil.copy2('cpucycles/%s' % fn,'build/%s/cpucycles/%s' % (host,fn)) M = 'cpucycles/%s.o: cpucycles/%s.c\n' % (base,base) M += '\tscripts/compiledefault cpucycles %s c -I ../include-build\n' % base M += '\n' makefile = M + makefile with open('build/%s/cpucycles/options.inc' % host,'w') as f: f.write('#define NUMOPTIONS %d\n' % len(cpucyclesoptions)) f.write('#define DEFAULTOPTION (NUMOPTIONS-1)\n') f.write('\n') for cpucycles in cpucyclesoptions: f.write('extern long long cpucycles_ticks_%s_%s_setup(void);\n' % (cpucycles[0],cpucycles[1])) f.write('extern long long cpucycles_ticks_%s_%s(void);\n' % (cpucycles[0],cpucycles[1])) f.write('\n') f.write('struct {\n') f.write(' const char *implementation;\n') f.write(' long long (*ticks_setup)(void);\n') f.write(' long long (*ticks)(void);\n') f.write('} options[NUMOPTIONS] = {\n') for cpucycles in cpucyclesoptions: f.write('{ "%s-%s", cpucycles_ticks_%s_%s_setup, cpucycles_ticks_%s_%s },\n' % (cpucycles[0],cpucycles[1],cpucycles[0],cpucycles[1],cpucycles[0],cpucycles[1])) f.write('} ;\n') with open('build/%s/cpucycles/staticlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('rm -f package/lib/lib%s.a\n' % libcpucycles) f.write('ar cr package/lib/lib%s.a "$@"\n' % libcpucycles) f.write('ranlib package/lib/lib%s.a || :\n' % libcpucycles) f.write('chmod 644 package/lib/lib%s.a\n' % libcpucycles) os.chmod('build/%s/cpucycles/staticlib' % host,0o755) M = 'package/lib/lib%s.a: cpucycles/staticlib %s\n' % (libcpucycles,' '.join(cpucyclesofiles)) M += '\tcpucycles/staticlib %s\n' % ' '.join(cpucyclesofiles) M += '\n' makefile = M + makefile with open('build/%s/cpucycles/sharedlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('%s -shared \\\n' % firstcompiler) if rpath: f.write(' -Wl,-rpath=%s \\\n' % rpath) f.write(' -Wl,-soname,lib%s.so.1 \\\n' % libcpucycles) f.write(' -o package/lib/lib%s.so.1 \\\n' % libcpucycles) f.write(' "$@"\n') f.write('chmod 644 package/lib/lib%s.so.1\n' % libcpucycles) os.chmod('build/%s/cpucycles/sharedlib' % host,0o755) M = 'package/lib/lib%s.so.1: cpucycles/sharedlib %s\n' % (libcpucycles,' '.join(cpucyclesofiles)) M += '\tcpucycles/sharedlib %s\n' % ' '.join(cpucyclesofiles) M += '\n' makefile = M + makefile M = 'package/lib/lib%s.so: package/lib/lib%s.so.1\n' % (libcpucycles,libcpucycles) M += '\trm -f package/lib/lib%s.so\n' % libcpucycles M += '\tln -s lib%s.so.1 package/lib/lib%s.so\n' % (libcpucycles,libcpucycles) M += '\n' makefile = M + makefile # ----- command copytree('command','build/%s/command'%host) dirlinksym('build/%s/command'%host,'bin','../package/bin') dirlinksym('build/%s/command'%host,'lib','../package/lib') dirlinksym('build/%s/command'%host,'include-build','../include-build') dirlinksym('build/%s/command'%host,'include','../package/include') with open('build/%s/command/link' % host,'w') as f: f.write('#!/bin/sh\n') f.write('target="$1"; shift\n') f.write('%s \\\n' % firstcompiler) f.write(' -fvisibility=hidden \\\n') f.write(' -o "$target" "$@"\n') os.chmod('build/%s/command/link' % host,0o755) commands = [] for fn in sorted(os.listdir('command')): if not fn.endswith('.c'): continue libs = set() with open('command/%s' % fn) as f: for line in f: line = line.strip().split() if len(line) < 1: continue if line[0] != '#include': continue if '-lcpucycles' in line: libs.add('libcpucycles') if '-l25519' in line: libs.add('lib25519') if '-lrandombytes_kernel' in line: libs.add('librandombytes_kernel') libs = sorted(libs) # XXX: with more libs, might need non-default sort order for linking base = fn[:-2] M = 'command/%s.o: command/%s.c\n' % (base,base) M += '\tscripts/compiledefault command %s c -I include -I include-build\n' % base M += '\n' makefile = M + makefile M = 'package/bin/%s: command/%s.o%s\n' % (base,base,''.join(' package/lib/%s.%s' % (x,linktype) for x in libs)) M += '\tcd command && ./link bin/%s %s.o%s\n' % (base,base,''.join(' lib/%s.%s' % (x,linktype) for x in libs)) M += '\n' makefile = M + makefile commands += ['package/bin/%s' % base] M = 'commands: %s\n' % ' '.join(commands) M += '\n' makefile = M + makefile # ----- make install M = 'install: scripts/install default\n' M += '\tscripts/install %s\n' % prefix M += '\n' makefile = M + makefile # ----- make default M = 'default: package/lib/lib25519.a package/lib/lib25519.so package/lib/lib25519.so.1 \\\n' M += 'package/lib/lib%s.a package/lib/lib%s.so package/lib/lib%s.so.1 \\\n' % (librandombytes,librandombytes,librandombytes) M += 'package/lib/lib%s.a package/lib/lib%s.so package/lib/lib%s.so.1 \\\n' % (libcpucycles,libcpucycles,libcpucycles) M += 'commands\n' M += '\n' makefile = M + makefile with open('build/%s/Makefile' % host,'w') as f: f.write(makefile) # ----- build/0, build/Makefile dirlinksym('build','0',host) with tempfile.TemporaryDirectory(dir='build') as t: os.symlink(host,'%s/0' % t) os.rename('%s/0' % t,'build/0') with open('build/Makefile','w') as f: f.write('default:\n') f.write('\tcd %s && $(MAKE)\n' % host) f.write('\n') f.write('install:\n') f.write('\tcd %s && $(MAKE) install\n' % host) f.write('\n') f.write('clean:\n') f.write('\trm -r %s\n' % host)