-rwxr-xr-x 9067 librandombytes-20230919/configure raw
#!/usr/bin/env python3
import os
import shutil
import sys
import platform
import subprocess
import tempfile
prefix = '/usr/local'
clean = True
defaultimpl = 'kernel'
def hostsanitize(host):
host = host.split('-')[0]
host = ''.join(c for c in host if c in '_0123456789abcdefghijklmnopqrstuvwxyz')
for prefix,result in (
('amd64','amd64'), ('x86_64','amd64'),
('x86','x86'), ('i386','x86'), ('i686','x86'),
('arm64','arm64'), ('armv8','arm64'), ('aarch64','arm64'),
('arm','arm32'),
('riscv64','riscv64'),
('riscv','riscv32'),
('mips64','mips64'),
('mips','mips32'),
('ppc64','ppc64'), ('powerpc64','ppc64'),
('powerpc','ppc32'),
('ppc','ppc32'),
('sparc64','sparc64'), ('sparcv9','sparc64'), ('sun4u','sparc64'),
('sparc','sparc32'), ('sun','sparc32'),
):
if host.startswith(prefix): return result
return host
host = hostsanitize(platform.machine())
configurelog = ''
def log(x):
global configurelog
configurelog += x+'\n'
print(x)
makefile = ''
for arg in sys.argv[1:]:
if arg.startswith('--prefix='):
prefix = arg[9:]
continue
if arg.startswith('--host='):
host = hostsanitize(arg[7:])
continue
if arg == '--clean':
clean = True
continue
if arg == '--noclean':
clean = False
continue
raise ValueError('unrecognized argument %s' % arg)
echoargs = './configure'
echoargs += ' --prefix=%s' % prefix
echoargs += ' --host=%s' % host
if clean: echoargs += ' --clean'
if not clean: echoargs += ' --noclean'
log(echoargs)
if prefix[0] != '/':
raise ValueError('prefix %s is not an absolute path' % prefix)
if clean:
shutil.rmtree('build/%s' % host,ignore_errors=True)
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))
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)
if clean:
os.symlink('../..','build/%s/src' % host)
def copytree(src,dst,acceptfn=None):
# starting with python 3.8 can use shutil.copytree
# with dirs_exist_ok=True
# but want to support older versions of python too
# and want to symlink rather than copying
os.makedirs(dst,exist_ok=True)
for fn in sorted(os.listdir(src)):
srcfn = '%s/%s' % (src,fn)
if os.path.isdir(srcfn):
dstfn = '%s/%s' % (dst,fn)
copytree(srcfn,dstfn)
else:
if acceptfn is not None:
if not acceptfn(fn): continue
dirlinksym(dst,fn,'../'*(len(dst.split('/'))-2)+'src/'+srcfn)
shutil.copystat(src,dst)
copytree('scripts-build','build/%s/scripts' % host)
with open('project/library') as f:
projectlibrary = f.read().strip()
# ----- 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
firstcompiler = None
with open('compilers/default') as f:
for c in f.readlines():
c = c.strip()
cv = compilerversion(c)
if cv == None:
log('skipping default compiler %s' % c)
continue
log('using default compiler %s' % c)
firstcompiler = c
break
if firstcompiler is None:
raise ValueError('did not find a working compiler')
with open('build/%s/scripts/cdcompile' % host,'w') as f:
f.write('#!/bin/sh\n')
f.write('\n')
f.write('cd "$1"; shift\n')
f.write('exec %s "$@"\n' % firstcompiler)
os.chmod('build/%s/scripts/cdcompile' % host,0o755)
# ----- projectlibrary
def alternatives(dir,fn):
with open('%s/%s' % (dir,fn)) as f:
for line in f:
line = line.split()
if len(line) >= 3 and line[:2] == ['//','automatic-alternatives']:
return ' '.join(line[2:])
return '1'
objects = {}
for dir in 'kernel','openssl','include':
builddir = 'build/%s/%s' % (host,dir)
os.makedirs(builddir,exist_ok=True)
for fn in sorted(os.listdir(dir)):
dirlinksym(builddir,fn,'../src/%s/%s' % (dir,fn))
if dir == 'include':
shutil.copy2('include/%s'%fn,'build/%s/package/include/%s'%(host,fn))
if fn.endswith('.c'):
impl = alternatives(dir,fn)
base = fn[:-2]
M = '%s/%s.o: %s/%s.c' % (dir,base,dir,base)
for obj in impl.split()[1:]:
if obj.endswith('.o') and not obj.startswith('-l'):
M += ' %s/%s' % (dir,obj)
M += '\n'
M += '\tscripts/compilealternatives %s %s %s\n' % (dir,base,alternatives(dir,fn))
M += '\n'
makefile = M + makefile
if dir not in objects:
objects[dir] = []
objects[dir] += ['%s/%s.o'%(dir,base)]
for impl in sorted(objects):
M = 'package/lib/lib%s-%s.a: scripts/staticlib %s\n' % (projectlibrary,impl,' '.join(objects[impl]))
M += '\tscripts/staticlib lib%s-%s %s\n' % (projectlibrary,impl,' '.join(objects[impl]))
M += '\n'
makefile = M + makefile
M = 'package/lib/lib%s-%s.so.1: scripts/sharedlib %s\n' % (projectlibrary,impl,' '.join(objects[impl]))
if impl == 'openssl':
M += '\tscripts/sharedlib lib%s-%s %s -lcrypto\n' % (projectlibrary,impl,' '.join(objects[impl]))
else:
M += '\tscripts/sharedlib lib%s-%s %s\n' % (projectlibrary,impl,' '.join(objects[impl]))
M += '\n'
makefile = M + makefile
M = 'package/lib/lib%s-%s.so: package/lib/lib%s-%s.so.1\n' % (projectlibrary,impl,projectlibrary,impl)
M += '\trm -f package/lib/lib%s-%s.so\n' % (projectlibrary,impl)
M += '\tln -s lib%s-%s.so.1 package/lib/lib%s-%s.so\n' % (projectlibrary,impl,projectlibrary,impl)
M += '\n'
makefile = M + makefile
for link in 'a','so.1','so':
M = 'package/lib/lib%s.%s: package/lib/lib%s-%s.%s\n' % (projectlibrary,link,projectlibrary,defaultimpl,link)
M += '\trm -f package/lib/lib%s.%s\n' % (projectlibrary,link)
M += '\tln -s lib%s-%s.%s package/lib/lib%s.%s\n' % (projectlibrary,defaultimpl,link,projectlibrary,link)
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','../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
base = fn[:-2]
deps = 'command/%s.o'%base
link = 'cd command && ./link bin/%s %s.o'%(base,base)
syslink = ''
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 '-lm' in line:
syslink += ' -lm'
if '-l%s'%projectlibrary in line:
deps += ' package/lib/lib%s.so' % projectlibrary
link += ' lib/lib%s.so' % projectlibrary
link += syslink
M = 'command/%s.o: command/%s.c\n' % (base,base)
M += '\tscripts/compiledefault command %s c -I include\n' % base
M += '\n'
makefile = M + makefile
M = 'package/bin/%s: %s\n' % (base,deps)
M += '\t%s\n' % link
M += '\n'
makefile = M + makefile
commands += ['package/bin/%s' % base]
M = 'commands: %s\n' % ' '.join(commands)
M += '\n'
makefile = M + makefile
# ----- manual pages
for manpage in sorted(os.listdir('doc/man')):
section = 'man%s' % manpage[-1]
targetdir = 'build/%s/package/man/%s' % (host,section)
os.makedirs(targetdir,exist_ok=True)
shutil.copy2('doc/man/%s'%manpage,'%s/%s'%(targetdir,manpage))
# ----- make install
M = 'install: scripts/install default\n'
M += '\tscripts/install %s\n' % prefix
M += '\n'
makefile = M + makefile
# ----- make default
M = 'default: \\\n'
for impl in sorted(objects):
M += 'package/lib/lib%s-%s.a \\\n' % (projectlibrary,impl)
M += 'package/lib/lib%s-%s.so \\\n' % (projectlibrary,impl)
M += 'package/lib/lib%s-%s.so.1 \\\n' % (projectlibrary,impl)
M += 'package/lib/lib%s.a \\\n' % projectlibrary
M += 'package/lib/lib%s.so \\\n' % projectlibrary
M += 'package/lib/lib%s.so.1 \\\n' % projectlibrary
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 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)
# ----- finish
log('configure done')
with open('build/%s/configure.log'%host,'a') as f:
f.write(configurelog)
with open('build/%s/configure.log.latest'%host,'w') as f:
f.write(configurelog)