Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 110 additions & 1 deletion emsdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,111 @@ def build_llvm(tool):
return success


def build_ninja(tool):
debug_print('build_ninja(' + str(tool) + ')')
root = os.path.normpath(tool.installation_path())
src_root = os.path.join(root, 'src')
success = git_clone_checkout_and_pull(tool.download_url(), src_root, tool.git_branch)
if not success:
return False

build_dir = llvm_build_dir(tool)
build_root = os.path.join(root, build_dir)

build_type = decide_cmake_build_type(tool)

# Configure
cmake_generator = CMAKE_GENERATOR
args = []
if 'Visual Studio 16' in CMAKE_GENERATOR: # VS2019
# With Visual Studio 16 2019, CMake changed the way they specify target arch.
# Instead of appending it into the CMake generator line, it is specified
# with a -A arch parameter.
args += ['-A', 'x64' if tool.bitness == 64 else 'x86']
args += ['-Thost=x64']
elif 'Visual Studio' in CMAKE_GENERATOR and tool.bitness == 64:
cmake_generator += ' Win64'
args += ['-Thost=x64']

cmakelists_dir = os.path.join(src_root)
success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
if not success:
return False

# Make
success = make_build(build_root, build_type, 'x64' if tool.bitness == 64 else 'Win32')

if success:
bin_dir = os.path.join(root, 'bin')
mkdir_p(bin_dir)
exe_paths = [os.path.join(build_root, 'Release', 'ninja'), os.path.join(build_root, 'ninja')]
for e in exe_paths:
for s in ['.exe', '']:
ninja = e + s
if os.path.isfile(ninja):
dst = os.path.join(bin_dir, 'ninja' + s)
shutil.copyfile(ninja, dst)
os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)

return success


def build_ccache(tool):
debug_print('build_ccache(' + str(tool) + ')')
root = os.path.normpath(tool.installation_path())
src_root = os.path.join(root, 'src')
success = git_clone_checkout_and_pull(tool.download_url(), src_root, tool.git_branch)
if not success:
return False

build_dir = llvm_build_dir(tool)
build_root = os.path.join(root, build_dir)

build_type = decide_cmake_build_type(tool)

# Configure
cmake_generator = CMAKE_GENERATOR
args = ['-DZSTD_FROM_INTERNET=ON']
if 'Visual Studio 16' in CMAKE_GENERATOR: # VS2019
# With Visual Studio 16 2019, CMake changed the way they specify target arch.
# Instead of appending it into the CMake generator line, it is specified
# with a -A arch parameter.
args += ['-A', 'x64' if tool.bitness == 64 else 'x86']
args += ['-Thost=x64']
elif 'Visual Studio' in CMAKE_GENERATOR and tool.bitness == 64:
cmake_generator += ' Win64'
args += ['-Thost=x64']

cmakelists_dir = os.path.join(src_root)
success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
if not success:
return False

# Make
success = make_build(build_root, build_type, 'x64' if tool.bitness == 64 else 'Win32')

if success:
bin_dir = os.path.join(root, 'bin')
mkdir_p(bin_dir)
exe_paths = [os.path.join(build_root, 'Release', 'ccache'), os.path.join(build_root, 'ccache')]
for e in exe_paths:
for s in ['.exe', '']:
ccache = e + s
if os.path.isfile(ccache):
dst = os.path.join(bin_dir, 'ccache' + s)
shutil.copyfile(ccache, dst)
os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)

cache_dir = os.path.join(root, 'cache')
open(os.path.join(root, 'emcc_ccache.conf'), 'w').write('''# Set maximum cache size to 10 GB:
max_size = 10G
cache_dir = %s
''' % cache_dir)
mkdir_p(cache_dir)

return success


# Emscripten asm.js optimizer build scripts:
def optimizer_build_root(tool):
build_root = tool.installation_path().strip()
Expand Down Expand Up @@ -1898,6 +2003,10 @@ def install_tool(self):
success = build_fastcomp(self)
elif hasattr(self, 'custom_install_script') and self.custom_install_script == 'build_llvm':
success = build_llvm(self)
elif hasattr(self, 'custom_install_script') and self.custom_install_script == 'build_ninja':
success = build_ninja(self)
elif hasattr(self, 'custom_install_script') and self.custom_install_script == 'build_ccache':
success = build_ccache(self)
elif hasattr(self, 'git_branch'):
success = git_clone_checkout_and_pull(url, self.installation_path(), self.git_branch)
elif url.endswith(ARCHIVE_SUFFIXES):
Expand Down Expand Up @@ -1925,7 +2034,7 @@ def install_tool(self):
success = emscripten_post_install(self)
elif self.custom_install_script == 'emscripten_npm_install':
success = emscripten_npm_install(self, self.installation_path())
elif self.custom_install_script in ('build_fastcomp', 'build_llvm'):
elif self.custom_install_script in ('build_fastcomp', 'build_llvm', 'build_ninja', 'build_ccache'):
# 'build_fastcomp' is a special one that does the download on its
# own, others do the download manually.
pass
Expand Down
23 changes: 23 additions & 0 deletions emsdk_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,29 @@
"windows_url": "mingw_7.1.0_64bit.zip",
"activated_cfg": "MINGW_ROOT='%installation_dir%'",
"activated_path": "%installation_dir%/bin"
},
{
"id": "ninja",
"version": "git-release",
"bitness": 64,
"url": "https://github.com/ninja-build/ninja.git",
"git_branch": "release",
"activated_cfg": "NINJA=%installation_dir%/bin",
"activated_path": "%installation_dir%/bin",
"cmake_build_type": "Release",
"custom_install_script": "build_ninja"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just treat ninja like node an download the prebuilt binaries?

Looks like the zip files are easy to link to: https://github.com/ninja-build/ninja/releases

Or maybe just treat it like cmake itself and assume the developer has already installed it? Building from source seems like a less trodden path so have extra dependencies seems reasonable maybe? At least it seems like cmake and ninja should be treated in the same way.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly because of being able to change up ninja code in a custom branch, because of getting direct Apple M1 Mac support this way, and to get backwards compatibility support against whichever Xcode SDK and Windows SDK that I compile for myself. (I don't know the guaranteed min OS versions of the precompiled releases).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we at least try it? or at least have "download binary" as the default way to download ninja? (then only folks with unusual OS/hardware need to build from source, like we do for llvm)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have have patches to ninja planned?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not oppose adding prebuilt ninja as well, though I am not keen to work on that at the moment. Fortunately emsdk does allow a good structure to have both.

I do plan to change ninja to fix stdout printing issues on Windows. When one uses ninja, they lose colored output for error messages and all stdout gets needlessly buffered, resulting in EMCC_DEBUG being uncomfortable to use on Windows.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to simply use ninja pre-built bit I'm OK landing this as is.

Regarding the specifics of the ninja buffering issue. Are you talking about how the buffering causes the tools to skip adding color to their output? I agree it would be nice to find a fix for this, but I also really like how ninja buffers command and output rather than the nasty interleaving one gets with make VERVOSE=1 -jN.

},
{
"id": "ccache",
"version": "git-emscripten",
"bitness": 64,
"url": "https://github.com/juj/ccache.git",
"git_branch": "emscripten",
"activated_cfg": "EMCC_CCACHE=1",
"activated_path": "%installation_dir%/bin",
"activated_env": "EMCC_CCACHE=1;CCACHE_CONFIGPATH=%installation_dir%/emcc_ccache.conf",
"cmake_build_type": "Release",
"custom_install_script": "build_ccache"
}
],

Expand Down