Skip to content

Commit

Permalink
Experimental support for bulding system libraries via ninja
Browse files Browse the repository at this point in the history
The primary advantage of doing this is that it avoids having force
a completely rebuild of a system library when you want to rebuilt it.
Instead not have precise dependencies.
  • Loading branch information
sbc100 committed Sep 14, 2022
1 parent c7d7b22 commit c097a11
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 41 deletions.
2 changes: 1 addition & 1 deletion embuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def main():
if do_clear:
library.erase()
if do_build:
library.get_path()
library.build()
elif what == 'sysroot':
if do_clear:
shared.Cache.erase_file('sysroot_install.stamp')
Expand Down
11 changes: 6 additions & 5 deletions tools/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def get_lib_dir(self, absolute, varies=True):
path = Path(path, '-'.join(subdir))
return path

def get_lib_name(self, name, varies=True):
return str(self.get_lib_dir(absolute=False, varies=varies).joinpath(name))
def get_lib_name(self, name, varies=True, absolute=False):
return str(self.get_lib_dir(absolute=absolute, varies=varies).joinpath(name))

def erase_lib(self, name):
self.erase_file(self.get_lib_name(name))
Expand All @@ -127,7 +127,7 @@ def get_lib(self, libname, *args, **kwargs):

# Request a cached file. If it isn't in the cache, it will be created with
# the given creator function
def get(self, shortname, creator, what=None, force=False):
def get(self, shortname, creator, what=None, force=False, quiet=False):
cachename = Path(self.dirname, shortname)
# Check for existence before taking the lock in case we can avoid the
# lock completely.
Expand All @@ -147,11 +147,12 @@ def get(self, shortname, creator, what=None, force=False):
what = 'system library'
else:
what = 'system asset'
message = f'generating {what}: {shortname}... (this will be cached in "{cachename}" for subsequent builds)'
message = f'generating {what}: "{cachename}"'
logger.info(message)
utils.safe_ensure_dirs(cachename.parent)
creator(str(cachename))
assert cachename.exists()
logger.info(' - ok')
if not quiet:
logger.info(' - ok')

return str(cachename)
2 changes: 1 addition & 1 deletion tools/gen_struct_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def inspect_headers(headers, cflags):
# TODO(sbc): If we can remove EM_EXCLUSIVE_CACHE_ACCESS then this would not longer be needed.
shared.check_sanity()

compiler_rt = system_libs.Library.get_usable_variations()['libcompiler_rt'].get_path()
compiler_rt = system_libs.Library.get_usable_variations()['libcompiler_rt'].build()

# Close all unneeded FDs.
os.close(src_file[0])
Expand Down
44 changes: 31 additions & 13 deletions tools/ports/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,31 @@ def build_port(src_dir, output_path, port_name, includes=[], flags=[], exclude_f
for include in includes:
cflags.append('-I' + include)

commands = []
objects = []
for src in srcs:
relpath = os.path.relpath(src, src_dir)
obj = os.path.join(build_dir, relpath) + '.o'
dirname = os.path.dirname(obj)
if not os.path.exists(dirname):
os.makedirs(dirname)
commands.append([shared.EMCC, '-c', src, '-o', obj] + cflags)
objects.append(obj)

system_libs.run_build_commands(commands)
system_libs.create_lib(output_path, objects)
if system_libs.USE_NINJA:
if not os.path.exists(build_dir):
os.makedirs(build_dir)
ninja_file = os.path.join(build_dir, 'build.ninja')
system_libs.ensure_sysroot()
system_libs.create_ninja_file(srcs, ninja_file, output_path, cflags=cflags)
cmd = ['ninja', '-C', build_dir]
if shared.PRINT_STAGES:
cmd.append('-v')
shared.check_call(cmd, env=system_libs.clean_env())
else:
commands = []
objects = []
for src in srcs:
relpath = os.path.relpath(src, src_dir)
obj = os.path.join(build_dir, relpath) + '.o'
dirname = os.path.dirname(obj)
if not os.path.exists(dirname):
os.makedirs(dirname)
commands.append([shared.EMCC, '-c', src, '-o', obj] + cflags)
objects.append(obj)

system_libs.run_build_commands(commands)
system_libs.create_lib(output_path, objects)

return output_path

@staticmethod
Expand Down Expand Up @@ -274,6 +286,12 @@ def clear_project_build(name):
utils.delete_dir(build_dir)
return build_dir

@staticmethod
def write_file(filename, contents):
if os.path.exists(filename) and utils.read_file(filename) == contents:
return
utils.write_file(filename, contents)


def dependency_order(port_list):
# Perform topological sort of ports according to the dependency DAG
Expand Down
3 changes: 1 addition & 2 deletions tools/ports/boost_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import logging
import os
from pathlib import Path

TAG = '1.75.0'
HASH = '8c38be1ebef1b8ada358ad6b7c9ec17f5e0a300e8085db3473a13e19712c95eeb3c3defacd3c53482eb96368987c4b022efa8da2aac2431a154e40153d3c3dcd'
Expand All @@ -31,7 +30,7 @@ def create(final):
# this is needed as emscripted ports expect this, even if it is not used
dummy_file = os.path.join(source_path, 'dummy.cpp')
shared.safe_ensure_dirs(os.path.dirname(dummy_file))
Path(dummy_file).write_text('static void dummy() {}')
ports.write_file(dummy_file, 'static void dummy() {}')

ports.build_port(source_path, final, 'boost_headers', srcs=['dummy.cpp'])

Expand Down
2 changes: 1 addition & 1 deletion tools/ports/freetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def get(ports, settings, shared):

def create(final):
source_path = os.path.join(ports.get_dir(), 'freetype', 'FreeType-' + TAG)
Path(source_path, 'include/ftconfig.h').write_text(ftconf_h)
ports.write_file(Path(source_path, 'include/ftconfig.h'), ftconf_h)
ports.install_header_dir(os.path.join(source_path, 'include'),
target=os.path.join('freetype2'))

Expand Down
2 changes: 1 addition & 1 deletion tools/ports/libjpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def get(ports, settings, shared):
def create(final):
logging.info('building port: libjpeg')
source_path = os.path.join(ports.get_dir(), 'libjpeg', 'jpeg-9c')
Path(source_path, 'jconfig.h').write_text(jconfig_h)
ports.write_file(Path(source_path, 'jconfig.h'), jconfig_h)
ports.install_headers(source_path)
excludes = [
'ansi2knr.c', 'cjpeg.c', 'ckconfig.c', 'djpeg.c', 'example.c',
Expand Down
2 changes: 1 addition & 1 deletion tools/ports/libmodplug.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def create(final):
src_dir = os.path.join(source_path, 'src')
libmodplug_path = os.path.join(src_dir, 'libmodplug')

Path(source_path, 'config.h').write_text(config_h)
ports.write_file(Path(source_path, 'config.h'), config_h)

flags = [
'-Wno-deprecated-register',
Expand Down
2 changes: 1 addition & 1 deletion tools/ports/libpng.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def create(final):
logging.info('building port: libpng')

source_path = os.path.join(ports.get_dir(), 'libpng', 'libpng-' + TAG)
Path(source_path, 'pnglibconf.h').write_text(pnglibconf_h)
ports.write_file(Path(source_path, 'pnglibconf.h'), pnglibconf_h)
ports.install_headers(source_path)

flags = ['-sUSE_ZLIB=1']
Expand Down
4 changes: 2 additions & 2 deletions tools/ports/mpg123.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def create(final):
libmpg123_path = os.path.join(src_path, 'libmpg123')
compat_path = os.path.join(src_path, 'compat')

Path(src_path, 'config.h').write_text(config_h)
Path(libmpg123_path, 'mpg123.h').write_text(mpg123_h)
ports.write_file(Path(src_path, 'config.h'), config_h)
ports.write_file(Path(libmpg123_path, 'mpg123.h'), mpg123_h)

# copy header to a location so it can be used as 'MPG123/'
ports.install_headers(libmpg123_path, pattern="*123.h", target='')
Expand Down
2 changes: 1 addition & 1 deletion tools/ports/ogg.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def create(final):
logging.info('building port: ogg')

source_path = os.path.join(ports.get_dir(), 'ogg', 'Ogg-' + TAG)
Path(source_path, 'include', 'ogg', 'config_types.h').write_text(config_types_h)
ports.write_file(Path(source_path, 'include', 'ogg', 'config_types.h'), config_types_h)
ports.install_header_dir(os.path.join(source_path, 'include', 'ogg'), 'ogg')
ports.build_port(os.path.join(source_path, 'src'), final, 'ogg')

Expand Down
3 changes: 1 addition & 2 deletions tools/ports/zlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# found in the LICENSE file.

import os
from pathlib import Path

VERSION = '1.2.12'
HASH = 'cc2366fa45d5dfee1f983c8c51515e0cff959b61471e2e8d24350dea22d3f6fcc50723615a911b046ffc95f51ba337d39ae402131a55e6d1541d3b095d6c0a14'
Expand All @@ -19,7 +18,7 @@ def get(ports, settings, shared):

def create(final):
source_path = os.path.join(ports.get_dir(), 'zlib', 'zlib-' + VERSION)
Path(source_path, 'zconf.h').write_text(zconf_h)
ports.write_file(os.path.join(source_path, 'zconf.h'), zconf_h)
ports.install_headers(source_path)

# build
Expand Down
Loading

0 comments on commit c097a11

Please sign in to comment.