-rwxr-xr-x 10321 libcpucycles-20240318/configure raw
#!/usr/bin/env python3
import os
import shutil
import sys
import platform
import subprocess
import tempfile
prefix = '/usr/local'
clean = True
darwin = platform.system() == 'Darwin'
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())
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
if arg == '--darwin':
darwin = True
continue
if arg == '--nodarwin':
darwin = 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'
if darwin: echoargs += ' --darwin'
if not darwin: echoargs += ' --nodarwin'
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)
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)
# ----- build scripts
os.makedirs('build/%s/scripts'%host,exist_ok=True)
dirlinksym('build/%s/scripts'%host,'install','../src/scripts-build/install')
# ----- shared-library variations
so = 'dylib' if darwin else 'so'
so1 = '1.dylib' if darwin else 'so.1'
soname = 'install_name' if darwin else 'soname'
syslibs = '-lm' if darwin else '-lm -lrt'
# ----- 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:
print('skipping default compiler %s' % c)
continue
print('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/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(' "$@" \\\n')
f.write(' -c "$base.$ext"\n')
os.chmod('build/%s/scripts/compiledefault' % host,0o755)
# ----- libcpucycles
os.makedirs('build/%s/cpucycles' % host,exist_ok=True)
os.makedirs('build/%s/package/man/man1' % host,exist_ok=True)
os.makedirs('build/%s/package/man/man3' % host,exist_ok=True)
dirlinksym('build/%s/cpucycles'%host,'cpucycles.h','../src/cpucycles/cpucycles.h')
dirlinksym('build/%s/cpucycles'%host,'cpucycles_internal.h','../src/cpucycles/cpucycles_internal.h')
shutil.copy2('cpucycles/cpucycles.h','build/%s/package/include/cpucycles.h'%host)
shutil.copy2('doc/man/cpucycles-info.1','build/%s/package/man/man1/cpucycles-info.1'%host)
shutil.copy2('doc/man/cpucycles.3','build/%s/package/man/man3/cpucycles.3'%host)
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(' -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(' *) echo "[1;34mskipping option that did not compile[0m" ;;\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]
dirlinksym('build/%s/cpucycles'%host,'try-%s.c'%base,'../src/cpucycles/%s.c'%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' % tuple(cpucycles)
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]
dirlinksym('build/%s/cpucycles'%host,fn,'../src/cpucycles/%s'%fn)
M = 'cpucycles/%s.o: cpucycles/%s.c\n' % (base,base)
M += '\tscripts/compiledefault cpucycles %s c\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('static 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')
dirlinksym('build/%s/scripts'%host,'staticlib','../src/scripts-build/staticlib')
M = 'package/lib/libcpucycles.a: scripts/staticlib %s\n' % ' '.join(cpucyclesofiles)
M += '\tscripts/staticlib %s\n' % ' '.join(cpucyclesofiles)
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(f' -Wl,-{soname},libcpucycles.{so1} \\\n')
f.write(f' -o package/lib/libcpucycles.{so1} \\\n')
f.write(' "$@"\n')
f.write(f'chmod 644 package/lib/libcpucycles.{so1}\n')
os.chmod('build/%s/scripts/sharedlib' % host,0o755)
M = f'package/lib/libcpucycles.{so1}: scripts/sharedlib %s\n' % ' '.join(cpucyclesofiles)
M += '\tscripts/sharedlib %s\n' % ' '.join(cpucyclesofiles)
M += '\n'
makefile = M + makefile
M = f'package/lib/libcpucycles.{so}: package/lib/libcpucycles.{so1}\n'
M += f'\trm -f package/lib/libcpucycles.{so}\n'
M += f'\tln -s libcpucycles.{so1} package/lib/libcpucycles.{so}\n'
M += '\n'
makefile = M + makefile
# ----- command
os.makedirs('build/%s/command'%host)
for c in sorted(os.listdir('command')):
dirlinksym('build/%s/command'%host,c,'../src/command/%s'%c)
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(' -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 = ['libcpucycles']
base = fn[:-2]
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: command/%s.o%s\n' % (base,base,''.join(' package/lib/%s.%s' % (x,so) for x in libs))
M += f'\tcd command && ./link bin/%s %s.o%s {syslibs}\n' % (base,base,''.join(' lib/%s.%s' % (x,so) 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 = f'default: package/lib/libcpucycles.a package/lib/libcpucycles.{so} package/lib/libcpucycles.{so1} \\\n'
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)