Skip to content

Commit

Permalink
Merge branch 'release/1.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
mjansson committed May 14, 2016
2 parents edffe37 + 0089f76 commit b1226eb
Show file tree
Hide file tree
Showing 198 changed files with 11,636 additions and 6,031 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ build/xcode/foundation/build
#Doxygen generated
doc/html

#Local config
SConfig
#Coverity scan
cov-int/
cov-int.*

#################
## Visual Studio
Expand Down Expand Up @@ -80,6 +81,8 @@ SConfig
*.dotCover
*.lastbuildstate
*.unsuccessfulbuild
*.opendb
*.VC.db

## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,38 @@

1.5.0

Added a minimal in-place JSON parser. Also parses simplified JSON.

Added implementation SHA-2 256 and 512 bit algorithms, including uint256_t and uint512_t
representation data types with string conversions.

Removed configuration repository since it is mostly replaced by JSON parser.

Changed byte order representation of raw digest from md5_get_digest_raw to generate
correct string representation using string_from_uint128.

Changed environment_home_directory to environment_application_directory and modify
implementations to generate a application-specific path for persistent storage. Removed
application config_dir declaration.

Changed crash_* functions to more aptly named exception_* and added support for
non-Microsoft compilers on Windows.

Changed name of error callback and log callback to "handler" to unify naming with
exception handling.

Support for building as a shared object (dynamic library).

Support for Intel, clang and gcc compilers on Windows.

Android build now requires NDK r11 and uses clang by default, with built in
thread local storage support instead of old pthread api wrappers.

Refactored the ninja build generator into modules to be easier to extend and maintain
instead of a single monolithic file. Minor changes in generator interface. Build only
x86-64 target on Windows by default (x86 still supported).


1.4.1

Thread API change. Threads are now explicit structures instead of reference counted
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ functions to write applications and games in a platform-independent fashion. It
* String handling in UTF-8 and UTF-16
* Murmur hasing and statically hashed strings
* Math support for 32 and 64 bit floats
* Configuration repository with config file I/O
* JSON/SJSON parser
* SHA256/SHA512 digest
* Application, environment and system queries and control
* Regular expressions
* Crash utilities (SEH, signals)
* Exception utilities (SEH, signals)

It is written with the following API design principles in mind:

Expand Down
6 changes: 5 additions & 1 deletion ROADMAP
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Unify all string apis to be inherently length aware to increase security and min
Pass PC-Lint tests with minimal suppressions
95% code coverage in test suite

1.4.2
1.5.0
Example application and documentation
Improve overview and setup documentation
Support Intel, clang and gcc compilers on Windows
Support building as shared object/dynamic library
Add JSON parsing
Add SHA256/SHA512 digest
2 changes: 1 addition & 1 deletion build/foundation.sublime-project
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"working_dir": "${project_path:${folder:${file_path}}}/..",
}
],
"translate_tabs_to_spaces": false,
"use_tab_stops": true,
"translate_tabs_to_spaces": false,
"trim_trailing_white_space_on_save": true,
"settings":
{
Expand Down
298 changes: 298 additions & 0 deletions build/ninja/android.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
#!/usr/bin/env python

"""Ninja toolchain abstraction for Android platform"""

import os
import urlparse
import subprocess

import toolchain

def make_target(toolchain, host, target):
return Android(toolchain, host, target)

class Android(object):
def __init__(self, toolchain, host, target):
self.host = host

if host.is_windows():
self.exe_suffix = '.exe'
else:
self.exe_suffix = ''

self.javaccmd = toolchain.mkdircmd('$outpath') + ' && $javac -d $outpath -classpath $outpath -sourcepath $sourcepath -target 1.5 -bootclasspath $androidjar -g -source 1.5 -Xlint:-options $in'
self.dexcmd = '$dex --dex --output $out $in'
self.aaptcmd = toolchain.cdcmd('$apkbuildpath') + ' && $aapt p -f -m -M AndroidManifest.xml -F $apk -I $androidjar -S res --debug-mode --no-crunch -J gen $aaptflags'
self.aaptdeploycmd = toolchain.cdcmd('$apkbuildpath') + ' && $aapt c -S res -C bin/res && $aapt p -f -m -M AndroidManifest.xml -F $apk -I $androidjar -S bin/res -S res -J gen $aaptflags'
self.aaptaddcmd = toolchain.cdcmd('$apkbuildpath') + ' && ' + toolchain.copycmd('$apksource', '$apk' ) + ' && $aapt a $apk $apkaddfiles'
self.zipaligncmd = '$zipalign -f 4 $in $out'
self.jarsignercmd = '$jarsigner $timestamp -sigalg SHA1withRSA -digestalg SHA1 -keystore $keystore -storepass $keystorepass -keypass $keypass -signedjar $out $in $keyalias $proxy'
self.zipcmd = '$zip -r -9 $out $in $implicitin'

def initialize_toolchain(self):
self.ndkpath = os.getenv('NDK_HOME', '')
self.sdkpath = os.getenv('ANDROID_HOME', '')
self.sysroot = ''
self.platformversion = '21'
self.gcc_toolchainversion = '4.9'
self.tsacert = ''
self.tsa = ''
self.javasdk = ''
self.keystore = ''
self.keyalias = ''
self.keystorepass = ''
self.keypass = ''
self.proxy = ''

self.archname = dict()
self.archname['x86'] = 'x86'
self.archname['x86-64'] = 'x86_64'
self.archname['arm6'] = 'arm'
self.archname['arm7'] = 'arm'
self.archname['arm64'] = 'arm64'
self.archname['mips'] = 'mips'
self.archname['mips64'] = 'mips64'

self.archpath = dict()
self.archpath['x86'] = 'x86'
self.archpath['x86-64'] = 'x86-64'
self.archpath['arm6'] = 'armeabi'
self.archpath['arm7'] = 'armeabi-v7a'
self.archpath['arm64'] = 'arm64-v8a'
self.archpath['mips'] = 'mips'
self.archpath['mips64'] = 'mips64'

self.gcc_toolchainname = dict()
self.gcc_toolchainname['x86'] = 'x86-' + self.gcc_toolchainversion
self.gcc_toolchainname['x86-64'] = 'x86_64-' + self.gcc_toolchainversion
self.gcc_toolchainname['arm6'] = 'arm-linux-androideabi-' + self.gcc_toolchainversion
self.gcc_toolchainname['arm7'] = 'arm-linux-androideabi-' + self.gcc_toolchainversion
self.gcc_toolchainname['arm64'] = 'aarch64-linux-android-' + self.gcc_toolchainversion
self.gcc_toolchainname['mips'] = 'mipsel-linux-android-' + self.gcc_toolchainversion
self.gcc_toolchainname['mips64'] = 'mips64el-linux-android-' + self.gcc_toolchainversion

self.gcc_toolchainprefix = dict()
self.gcc_toolchainprefix['x86'] = 'i686-linux-android-'
self.gcc_toolchainprefix['x86-64'] = 'x86_64-linux-android-'
self.gcc_toolchainprefix['arm6'] = 'arm-linux-androideabi-'
self.gcc_toolchainprefix['arm7'] = 'arm-linux-androideabi-'
self.gcc_toolchainprefix['arm64'] = 'aarch64-linux-android-'
self.gcc_toolchainprefix['mips'] = 'mipsel-linux-android-'
self.gcc_toolchainprefix['mips64'] = 'mips64el-linux-android-'

if self.host.is_windows():
if os.getenv('PROCESSOR_ARCHITECTURE', 'AMD64').find('64') != -1:
self.hostarchname = 'windows-x86_64'
else:
self.hostarchname = 'windows-x86'
elif self.host.is_linux():
localarch = subprocess.check_output(['uname', '-m']).strip()
if localarch == 'x86_64':
self.hostarchname = 'linux-x86_64'
else:
self.hostarchname = 'linux-x86'
elif self.host.is_macosx():
self.hostarchname = 'darwin-x86_64'

def build_toolchain(self):
buildtools_path = os.path.join(self.sdkpath, 'build-tools')
buildtools_list = [item for item in os.listdir(buildtools_path) if os.path.isdir(os.path.join(buildtools_path, item))]
buildtools_list.sort(key = lambda s: map(int, s.split('-')[0].split('.')))

self.buildtools_path = os.path.join(self.sdkpath, 'build-tools', buildtools_list[-1])
self.android_jar = os.path.join(self.sdkpath, 'platforms', 'android-' + self.platformversion, 'android.jar')

self.javac = 'javac'
self.jarsigner = 'jarsigner'
if self.javasdk != '':
self.javac = os.path.join(self.javasdk, 'bin', self.javac)
self.jarsigner = os.path.join(self.javasdk, 'bin', self.jarsigner)
if self.host.is_windows():
self.dex = os.path.join(self.buildtools_path, 'dx.bat')
else:
self.dex = os.path.join(self.buildtools_path, 'dx' + self.exe_suffix)
if not os.path.isfile(self.dex):
self.dex = os.path.join(self.sdkpath, 'tools', 'dx' + self.exe_suffix)
self.aapt = os.path.join(self.buildtools_path, 'aapt' + self.exe_suffix)
self.zipalign = os.path.join(self.buildtools_path, 'zipalign' + self.exe_suffix)
if not os.path.isfile( self.zipalign ):
self.zipalign = os.path.join(self.sdkpath, 'tools', 'zipalign' + self.exe_suffix)

def parse_prefs(self, prefs):
if 'android' in prefs:
androidprefs = prefs['android']
if 'ndkpath' in androidprefs:
self.ndkpath = os.path.expanduser(androidprefs['ndkpath'])
if 'sdkpath' in androidprefs:
self.sdkpath = os.path.expanduser(androidprefs['sdkpath'])
if 'platformversion' in androidprefs:
self.platformversion = androidprefs['platformversion']
if 'gccversion' in androidprefs:
self.gcc_toolchainversion = androidprefs['gccversion']
if 'tsacert' in androidprefs:
self.tsacert = androidprefs['tsacert']
if 'tsa' in androidprefs:
self.tsa = androidprefs['tsa']
if 'javasdk' in androidprefs:
self.javasdk = androidprefs['javasdk']
if 'keystore' in androidprefs:
self.keystore = androidprefs['keystore']
if 'keyalias' in androidprefs:
self.keyalias = androidprefs['keyalias']
if 'keystorepass' in androidprefs:
self.keystorepass = androidprefs['keystorepass']
if 'keypass' in androidprefs:
self.keypass = androidprefs['keypass']
if 'proxy' in androidprefs:
self.proxy = androidprefs['proxy']
if self.proxy != '':
defstr = "-J-Dhttp.proxy"
url = urlparse.urlparse(self.proxy)
if url.scheme == 'https':
defstr = "-J-Dhttps.proxy"
host = url.netloc
port = ''
username = ''
password = ''
if '@' in host:
username, host = host.split(':', 1)
password, host = host.split('@', 1)
if ':' in host:
host, port = host.split(':', 1)
self.proxy = defstr + "Host=" + host
if port != '':
self.proxy += " " + defstr + "Port=" + port
if username != '':
self.proxy += " " + defstr + "User=" + username
if password != '':
self.proxy += " " + defstr + "Password=" + password

def write_variables(self, writer):
writer.variable('ndk', self.ndkpath)
writer.variable('sdk', self.sdkpath)
writer.variable('sysroot', self.sysroot)
writer.variable('androidjar', self.android_jar )
writer.variable('apkbuildpath', '')
writer.variable('apk', '')
writer.variable('apksource', '')
writer.variable('apkaddfiles', '')
writer.variable('javac', self.javac)
writer.variable('dex', self.dex)
writer.variable('aapt', self.aapt)
writer.variable('zipalign', self.zipalign)
writer.variable('jarsigner', self.jarsigner)
writer.variable('aaptflags', '')
writer.variable('timestamp', '')
writer.variable('keystore', self.keystore)
writer.variable('keyalias', self.keyalias)
writer.variable('keystorepass', self.keystorepass)
writer.variable('keypass', self.keypass)
writer.variable('proxy', self.proxy)

def write_rules(self, writer):
writer.rule('aapt', command = self.aaptcmd, description = 'AAPT $out')
writer.rule('aaptdeploy', command = self.aaptdeploycmd, description = 'AAPT $out')
writer.rule('aaptadd', command = self.aaptaddcmd, description = 'AAPT $out')
writer.rule('javac', command = self.javaccmd, description = 'JAVAC $in')
writer.rule('dex', command = self.dexcmd, description = 'DEX $out')
writer.rule('jarsigner', command = self.jarsignercmd, description = 'JARSIGNER $out')
writer.rule('zipalign', command = self.zipaligncmd, description = 'ZIPALIGN $out')
writer.rule('zip', command = self.zipcmd, description = 'ZIP $out')

def make_sysroot_path(self, arch):
return os.path.join(self.ndkpath, 'platforms', 'android-' + self.platformversion, 'arch-' + self.archname[arch])

def make_gcc_toolchain_path(self, arch):
return os.path.join(self.ndkpath, 'toolchains', self.gcc_toolchainname[arch], 'prebuilt', self.hostarchname)

def make_gcc_bin_path(self, arch):
return os.path.join(self.make_gcc_toolchain_path(arch), 'bin', self.gcc_toolchainprefix[arch])

def archname(self):
return self.archname

def archpath(self):
return self.archpath

def hostarchname(self):
return self.hostarchname

def apk(self, toolchain, writer, module, archbins, javasources, outpath, binname, basepath, config, implicit_deps, resources):
buildpath = os.path.join('$buildpath', config, 'apk', binname)
baseapkname = binname + ".base.apk"
unsignedapkname = binname + ".unsigned.apk"
unalignedapkname = binname + ".unaligned.apk"
apkname = binname + ".apk"
apkfiles = []
libfiles = []
locallibs = []
resfiles = []
manifestfile = []

writer.comment('Make APK')
for _, value in archbins.iteritems():
for archbin in value:
archpair = os.path.split(archbin)
libname = archpair[1]
arch = os.path.split(archpair[0])[1]
locallibpath = os.path.join('lib', self.archpath[arch], libname)
archpath = os.path.join(buildpath, locallibpath)
locallibs += [locallibpath + ' ']
libfiles += toolchain.copy(writer, archbin, archpath)
for resource in resources:
filename = os.path.split(resource)[1]
if filename == 'AndroidManifest.xml':
manifestfile = toolchain.copy(writer, os.path.join(basepath, module, resource), os.path.join(buildpath, 'AndroidManifest.xml'))
else:
restype = os.path.split(os.path.split(resource)[0])[1]
if restype == 'asset':
pass #todo: implement
else:
resfiles += toolchain.copy(writer, os.path.join(basepath, module, resource), os.path.join(buildpath, 'res', restype, filename))

#Make directories
gendir = toolchain.mkdir(writer, os.path.join(buildpath, 'gen'))
bindir = toolchain.mkdir(writer, os.path.join(buildpath, 'bin'))
binresdir = toolchain.mkdir(writer, os.path.join(buildpath, 'bin', 'res'), order_only = bindir)
alldirs = gendir + bindir + binresdir

aaptvars = [('apkbuildpath', buildpath), ('apk', baseapkname)]
aaptout = os.path.join(buildpath, baseapkname)
if config == 'deploy':
baseapkfile = writer.build(aaptout, 'aaptdeploy', manifestfile, variables = aaptvars, implicit = manifestfile + resfiles, order_only = alldirs)
else:
baseapkfile = writer.build(aaptout, 'aapt', manifestfile, variables = aaptvars, implicit = manifestfile + resfiles, order_only = alldirs)

#Compile java code
javafiles = []
localjava = []
if javasources != []:
#self.javaccmd = '$javac -d $outpath -classpath $outpath -sourcepath $sourcepath -target 1.5 -bootclasspath $androidjar -g -source 1.5 -Xlint:-options $in'
#self.dexcmd = '$dex --dex --output $out $in'
javasourcepath = '.'
if self.host.is_windows():
javasourcepath += ';'
else:
javasourcepath += ':'
javasourcepath += os.path.join(buildpath, 'gen')
classpath = os.path.join(buildpath, 'classes')
javavars = [('outpath', classpath), ('sourcepath', javasourcepath)]
javaclasses = writer.build(classpath, 'javac', javasources, variables = javavars, implicit = baseapkfile)
localjava += ['classes.dex']
javafiles += writer.build(os.path.join(buildpath, 'classes.dex'), 'dex', classpath)

#Add native libraries and java classes to apk
aaptvars = [('apkbuildpath', buildpath), ('apk', unsignedapkname), ('apksource', baseapkname), ('apkaddfiles', toolchain.paths_forward_slash(locallibs + localjava))]
unsignedapkfile = writer.build(os.path.join(buildpath, unsignedapkname), 'aaptadd', baseapkfile, variables = aaptvars, implicit = libfiles + javafiles, order_only = alldirs)

#Sign the APK
jarsignervars = []
if self.tsacert != '':
jarsignervars += [('timestamp', '-tsacert ' + self.tsacert)]
elif self.tsa != '':
jarsignervars += [('timestamp', '-tsa ' + self.tsa)]
unalignedapkfile = writer.build(os.path.join(buildpath, unalignedapkname), 'jarsigner', unsignedapkfile, variables = jarsignervars)

#Run zipalign
outfile = writer.build(os.path.join(outpath, config, apkname), 'zipalign', unalignedapkfile)
return outfile
Loading

0 comments on commit b1226eb

Please sign in to comment.