Initial repository commit.
This commit is contained in:
103
README.txt
Normal file
103
README.txt
Normal file
@@ -0,0 +1,103 @@
|
||||
Emscripten SDK
|
||||
==============
|
||||
|
||||
To make it quick and easy to set up and maintain an Emscripten development environment, the whole Emscripten toolchain is available as a standalone Emscripten SDK. The SDK provides all the required tools, such as Clang, python node.js and Visual Studio integration along with an update mechanism that makes it simple to migrate to newer Emscripten versions as they are released.
|
||||
|
||||
Get the SDK
|
||||
-----------
|
||||
|
||||
To get started with Emscripten development quickly and hassle-free, grab one of the packages below:
|
||||
|
||||
Windows:
|
||||
* Emscripten SDK Web Installer (.exe): A NSIS installer that always gets you the latest Emscripten SDK from the web.
|
||||
* Emscripten SDK 1.5.6 Offline Installer (.exe): A NSIS installer that bundles together the Emscripten 1.5.6 toolchain as an offline-installable package.
|
||||
* Portable Emscripten SDK Web Installer (.zip): Portable version of the Emscripten SDK that does not require system installation privileges.
|
||||
|
||||
Note: Currently the Emscripten SDK is Windows-only, but it is being developed with the goal in mind of extending it to OSX and possibly Linux as well.
|
||||
|
||||
Installing using the NSIS Installer
|
||||
-----------------------------------
|
||||
|
||||
The NSIS installers register the Emscripten SDK as a 'standard' Windows application. To install the SDK, download a NSIS .exe file above, double-click on it, and run through the installer to perform the installation. After the installer finishes, the full Emscripten toolchain will be available in the directory that was chosen during the installation, and no other steps are necessary. If your system has Visual Studio 2010 installed, the vs-tool MSBuild plugin will be automatically installed as well.
|
||||
|
||||
Installing the Portable SDK
|
||||
---------------------------
|
||||
|
||||
The Portable Emscripten SDK is a no-installer version of the SDK package. It is identical to the NSIS installer, except that it does not interact with the Windows registry, which allows Emscripten to be used on a computer without administrative privileges, and the ability to migrate the installation from one location (directory or computer) to another by just copying/zipping up the directory contents.
|
||||
|
||||
If you want to use the Portable Emscripten SDK, the initial setup process is as follows:
|
||||
|
||||
1. Unzip the SDK to a directory of your choice. This directory will contain the Emscripten SDK.
|
||||
2. Open a command prompt to the directory of the SDK.
|
||||
3. Run `emsdk update`. This will fetch the latest registry of available tools.
|
||||
4. Run `emsdk install latest`. This will download and install the latest SDK tools.
|
||||
5. Run `emsdk activate latest`. This will set up ~/.emscripten to point to the SDK.
|
||||
|
||||
Whenever you change the location of the Portable SDK (e.g. take it to another computer), re-run step 5.
|
||||
|
||||
SDK Concepts
|
||||
------------
|
||||
|
||||
The Emscripten SDK is effectively a small package manager for tools that are used in conjunction with Emscripten. The following glossary highlights the important concepts to help understanding the internals of the SDK:
|
||||
|
||||
* <b>Tool</b>: The basic unit of software bundled in the SDK. A Tool has a name and a version. For example, 'clang-3.2-32bit' is a Tool that contains the 32-bit version of the Clang v3.2 compiler.
|
||||
* <b>SDK</b>: A set of tools. For example, 'sdk-1.5.6-32bit' is an SDK consisting of the tools clang-3.2-32bit, node-0.10.17-32bit, python-2.7.5.1-32bit and emscripten-1.5.6.
|
||||
* <b>Active Tool/SDK</b>: Emscripten stores compiler configuration in a user-specific file <b>~/.emscripten</b>. This file points to paths for Emscripten, Python, Clang and so on. If the file ~/.emscripten is configured to point to a Tool in a specific directory, then that tool is denoted as being <b>active</b>. The Emscripten Command Prompt always gives access to the currently active Tools. This mechanism allows switching between different SDK versions easily.
|
||||
* <b>emsdk</b>: This is the name of the manager script that Emscripten SDK is accessed through. Most operations are of the form `emsdk command`. To access the emsdk script, launch the Emscripten Command Prompt.
|
||||
|
||||
Using the SDK
|
||||
-------------
|
||||
|
||||
The tools in the Emscripten SDK can be accessed in various ways. Which one you use depends only on your preference.
|
||||
|
||||
##### Emscripten Command Prompt
|
||||
|
||||
Start the Emscripten Command Prompt from Start Menu -> All Programs -> Emscripten -> Emscripten Command Prompt. This will spawn a new command prompt that has all the tools for the currently activated SDK version set to PATH. The Emscripten Command Prompt is analogous to the Visual Studio Command Prompt that ships with installations of Visual Studio.
|
||||
|
||||
##### Global PATH Setup
|
||||
|
||||
If you would prefer that all command prompts in the system should have the Emscripten SDK tools in PATH, you can of course add them manually. Start the Emscripten Command Prompt to display an info line of all paths that should be added.
|
||||
|
||||
##### Use Visual Studio 2010
|
||||
|
||||
After installing the vs-tool plugin, a new 'Emscripten' configuration will appear to the list of all Solution Configurations in Visual Studio. Activating that configuration for a solution/project will make Visual Studio run the project build through Emscripten, producing .html or .js output, depending on the project properties you set up.
|
||||
|
||||
SDK Maintenance
|
||||
---------------
|
||||
|
||||
The following tasks are common with the Emscripten SDK:
|
||||
|
||||
##### How do I work the emsdk utility?
|
||||
|
||||
Run `emsdk help` or just `emsdk` to get information about all available commands.
|
||||
|
||||
##### How do I check the installation status and version of the SDK and tools?
|
||||
|
||||
To get a list of all currently installed tools and SDK versions, and all available tools, run `emsdk list`.
|
||||
* A line will be printed for each tool/SDK that is available for installation.
|
||||
* The text `INSTALLED` will be shown for each tool that is available for install.
|
||||
* If a tool/SDK is currently active, a star (*) will be shown next to it.
|
||||
|
||||
##### How do I install a tool/SDK version?
|
||||
|
||||
Run the command `emsdk install <tool/sdk name>` to download and install a new tool or an SDK version.
|
||||
|
||||
##### How do I remove a tool or an SDK?
|
||||
|
||||
Run the command `emsdk uninstall <tool/sdk name>` to delete the given tool or SDK from the local harddrive completely.
|
||||
|
||||
##### How do I check for updates to the Emscripten SDK?
|
||||
|
||||
The command `emsdk update` will fetch package information for all new tools and SDK versions. After that, run `emsdk install <tool/sdk name>` to install a new version.
|
||||
|
||||
##### How do I change the currently active SDK version?
|
||||
|
||||
You can toggle between different tools and SDK versions by running `emsdk activate <tool/sdk name>`.
|
||||
|
||||
Uninstalling the Emscripten SDK
|
||||
-------------------------------
|
||||
|
||||
If you installed the SDK using a NSIS installer, launch 'Control Panel' -> 'Uninstall a program' -> 'Emscripten SDK'.
|
||||
|
||||
If you want to remove a Portable SDK, just delete the directory where you put the Portable SDK into.
|
||||
|
||||
1
emcmdprompt.bat
Normal file
1
emcmdprompt.bat
Normal file
@@ -0,0 +1 @@
|
||||
@cmd /k call emsdk_add_path.bat
|
||||
662
emsdk
Normal file
662
emsdk
Normal file
@@ -0,0 +1,662 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, optparse, subprocess, urllib2, os, os.path, errno, zipfile, string, json, platform, shutil
|
||||
|
||||
emsdk_master_server = 'http://clb.demon.fi/emscripten/'
|
||||
emscripten_git_repo = 'git@github.com:kripken/emscripten.git'
|
||||
|
||||
WINDOWS = False
|
||||
if os.name == 'nt':
|
||||
WINDOWS = True
|
||||
|
||||
LINUX = False
|
||||
if platform.system() == 'Linux':
|
||||
LINUX = True
|
||||
|
||||
OSX = False
|
||||
if platform.mac_ver()[0] != '':
|
||||
OSX = True
|
||||
|
||||
# http://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
|
||||
def mkdir_p(path):
|
||||
if os.path.exists(path):
|
||||
return
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >2.5
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
pass
|
||||
else: raise
|
||||
|
||||
def num_files_in_directory(path):
|
||||
if not os.path.isdir(path):
|
||||
return 0
|
||||
return len([name for name in os.listdir(path) if os.path.isfile(os.path.join(path, name))])
|
||||
|
||||
# http://stackoverflow.com/questions/12886768/simple-way-to-unzip-file-in-python-on-all-oses
|
||||
def unzip(source_filename, dest_dir):
|
||||
if num_files_in_directory(dest_dir) > 0:
|
||||
print "File '" + source_filename + "' has already been unpacked, skipping."
|
||||
return True
|
||||
print "Unpacking '" + source_filename + "' to '" + dest_dir + "'"
|
||||
mkdir_p(dest_dir)
|
||||
with zipfile.ZipFile(source_filename) as zf:
|
||||
for member in zf.infolist():
|
||||
# Path traversal defense copied from
|
||||
# http://hg.python.org/cpython/file/tip/Lib/http/server.py#l789
|
||||
words = member.filename.split('/')
|
||||
# print "words: " + str(words)
|
||||
path = dest_dir
|
||||
for word in words[:-1]:
|
||||
drive, word = os.path.splitdrive(word)
|
||||
head, word = os.path.split(word)
|
||||
if word in (os.curdir, os.pardir, ''): continue
|
||||
path = os.path.join(path, word)
|
||||
# print "Extracting " + member.filename + " to " + path
|
||||
# zf.extract(member, path)
|
||||
zf.extract(member, dest_dir)
|
||||
return True
|
||||
|
||||
# This function interprets whether the given string looks like a path to a directory instead of a file, without looking at the actual filesystem.
|
||||
# 'a/b/c' points to directory, so does 'a/b/c/', but 'a/b/c.x' is parsed as a filename
|
||||
def path_points_to_directory(path):
|
||||
if path == '.':
|
||||
return True
|
||||
last_slash = max(path.rfind('/'), path.rfind('\\'))
|
||||
last_dot = path.rfind('.')
|
||||
no_suffix = last_dot < last_slash or last_dot == -1
|
||||
if no_suffix:
|
||||
return True
|
||||
suffix = path[last_dot:]
|
||||
if suffix == '.exe' or suffix == '.zip': # Very simple logic for the only file suffixes used by emsdk downloader. Other suffixes, like 'clang-3.2' are treated as dirs.
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def download_file(url, dstpath, download_even_if_exists=False):
|
||||
file_name = url.split('/')[-1]
|
||||
if path_points_to_directory(dstpath):
|
||||
file_name = os.path.join(dstpath, file_name)
|
||||
else:
|
||||
file_name = dstpath
|
||||
if os.path.exists(file_name) and not download_even_if_exists:
|
||||
print "File '" + file_name + "' already downloaded, skipping."
|
||||
return True
|
||||
u = urllib2.urlopen(url)
|
||||
mkdir_p(os.path.dirname(file_name))
|
||||
f = open(file_name, 'wb')
|
||||
meta = u.info()
|
||||
file_size = int(meta.getheaders("Content-Length")[0])
|
||||
print "Downloading: %s from %s Bytes: %s" % (file_name, url, file_size)
|
||||
|
||||
file_size_dl = 0
|
||||
block_sz = 8192
|
||||
while True:
|
||||
buffer = u.read(block_sz)
|
||||
if not buffer:
|
||||
break
|
||||
|
||||
file_size_dl += len(buffer)
|
||||
f.write(buffer)
|
||||
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
|
||||
status = status + chr(8)*(len(status)+1)
|
||||
print status,
|
||||
|
||||
f.close()
|
||||
return True
|
||||
|
||||
def run(cmd, cwd=None):
|
||||
process = subprocess.Popen(cmd, cwd=cwd, env=os.environ.copy())
|
||||
process.communicate()
|
||||
if process.returncode != 0:
|
||||
print str(cmd) + ' failed with error code ' + str(process.returncode) + '!'
|
||||
return process.returncode
|
||||
|
||||
def run_get_output(cmd, cwd=None):
|
||||
process = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, env=os.environ.copy())
|
||||
(stdout, stderr) = process.communicate()
|
||||
return (process.returncode, stdout, stderr)
|
||||
|
||||
warnonce_git_not_found = False
|
||||
|
||||
def GIT():
|
||||
global warnonce_git_not_found
|
||||
# git = 'git/1.8.3/bin/bin/git.exe'
|
||||
git = 'git/1.8.3/cmd/git.exe'
|
||||
try:
|
||||
(ret, stdout, stderr) = run_get_output([git, '--version'])
|
||||
if ret == 0:
|
||||
return git
|
||||
except:
|
||||
pass
|
||||
git = 'git'
|
||||
try:
|
||||
(ret, stdout, stderr) = run_get_output([git, '--version'])
|
||||
if ret == 0:
|
||||
return git
|
||||
except:
|
||||
pass
|
||||
if not warnonce_git_not_found:
|
||||
print "Warning: git executable was not found. Either install git manually and add it to PATH, or install the git tool via 'emsdk install git-1.8.3'"
|
||||
warnonce_git_not_found = True
|
||||
return 'git'
|
||||
|
||||
def git_repo_version(repo_path):
|
||||
(returncode, stdout, stderr) = run_get_output([GIT(), 'log', '-n', '1', '--pretty="%aD %H"'], cwd=repo_path)
|
||||
if returncode == 0:
|
||||
return stdout.strip()
|
||||
else:
|
||||
return ""
|
||||
|
||||
def git_clone(url, dstpath):
|
||||
if os.path.isdir(os.path.join(dstpath, '.git')):
|
||||
print "Repository '" + url + "' already cloned to directory '" + dstpath + "', skipping."
|
||||
return True
|
||||
mkdir_p(dstpath)
|
||||
return run([GIT(), 'clone', url, dstpath]) == 0
|
||||
|
||||
def git_checkout_and_pull(repo_path, branch):
|
||||
run([GIT(), 'fetch', 'origin'], repo_path)
|
||||
try:
|
||||
print "Fetching latest changes to the branch '" + branch + "' for '" + repo_path + "'..."
|
||||
run([GIT(), 'fetch', 'origin'], repo_path)
|
||||
# run([GIT, 'checkout', '-b', branch, '--track', 'origin/'+branch], repo_path)
|
||||
run([GIT(), 'checkout', '--quiet', branch], repo_path) # this line assumes that the user has not gone and manually messed with the repo and added new remotes to ambiguate the checkout.
|
||||
run([GIT(), 'merge', '--ff-only', 'origin/'+branch], repo_path) # this line assumes that the user has not gone and made local changes to the repo
|
||||
except:
|
||||
print 'git operation failed!'
|
||||
return False
|
||||
print "Successfully updated and checked out branch '" + branch + "' on repository '" + repo_path + "'"
|
||||
print "Current repository version: " + git_repo_version(repo_path)
|
||||
return True
|
||||
|
||||
def git_clone_checkout_and_pull(url, dstpath, branch):
|
||||
success = git_clone(url, dstpath)
|
||||
if not success:
|
||||
return False
|
||||
success = git_checkout_and_pull(dstpath, branch)
|
||||
return success
|
||||
|
||||
def download_and_unzip(zipfile, dst):
|
||||
success = download_file(emsdk_master_server + zipfile, 'zips/')
|
||||
if not success:
|
||||
return False
|
||||
return unzip('zips/'+zipfile, dst)
|
||||
|
||||
def to_unix_path(p):
|
||||
return p.replace('\\', '/')
|
||||
|
||||
# Returns the absolute pathname to the given path inside the Emscripten SDK.
|
||||
def sdk_path(path): return to_unix_path(os.path.join(os.path.dirname(os.path.realpath(__file__)), path))
|
||||
|
||||
def emsdk_path(): return to_unix_path(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
# Finds and returns a list of the directories that need to be added to PATH for the given set of tools.
|
||||
def get_required_path(active_tools):
|
||||
path_add = [emsdk_path()]
|
||||
for tool in active_tools:
|
||||
if hasattr(tool, 'activated_path'):
|
||||
path_add += [tool.activated_path.replace('%installation_dir%', sdk_path(tool.installation_dir()))]
|
||||
return path_add
|
||||
|
||||
# Returns the absolute path to the file '.emscripten' for the current user on this system.
|
||||
def dot_emscripten_path():
|
||||
return os.path.expanduser("~/.emscripten")
|
||||
|
||||
dot_emscripten = {}
|
||||
|
||||
def parse_key_value(line):
|
||||
if not line:
|
||||
return ('', '')
|
||||
eq = line.find('=')
|
||||
if eq != -1:
|
||||
key = line[0:eq].strip()
|
||||
value = line[eq+1:].strip()
|
||||
return (key, value)
|
||||
else:
|
||||
return (key, '')
|
||||
|
||||
def load_dot_emscripten():
|
||||
global dot_emscripten
|
||||
dot_emscripten = {}
|
||||
lines = []
|
||||
try:
|
||||
lines = open(dot_emscripten_path(), "r").read().split('\n')
|
||||
except:
|
||||
pass
|
||||
for line in lines:
|
||||
try:
|
||||
(key, value) = parse_key_value(line)
|
||||
if value != '':
|
||||
dot_emscripten[key] = value
|
||||
# print "Got '" + key + "' = '" + value + "'"
|
||||
except:
|
||||
pass
|
||||
|
||||
def generate_dot_emscripten(active_tools, temp_dir):
|
||||
#EMSCRIPTEN_ROOT = '$emscripten_root'
|
||||
#LLVM_ROOT = '$llvm_root'
|
||||
#PYTHON = '$python'
|
||||
#NODE_JS = '$node_js'
|
||||
template = string.Template(
|
||||
'''import os
|
||||
SPIDERMONKEY_ENGINE = ''
|
||||
V8_ENGINE = ''
|
||||
TEMP_DIR = '$temp_dir'
|
||||
COMPILER_ENGINE = NODE_JS
|
||||
JS_ENGINES = [NODE_JS]
|
||||
''')
|
||||
|
||||
# Make sure we have a working temp directory for the emscripten compiler to use.
|
||||
mkdir_p(sdk_path(temp_dir))
|
||||
|
||||
cfg = 'import os\n'
|
||||
|
||||
for tool in active_tools:
|
||||
tool_cfg = tool.activated_config()
|
||||
if tool_cfg:
|
||||
cfg += tool_cfg + '\n'
|
||||
|
||||
cfg += '''SPIDERMONKEY_ENGINE = ''
|
||||
V8_ENGINE = ''
|
||||
TEMP_DIR = ''' + "'" + sdk_path(temp_dir) + "'" + '''
|
||||
COMPILER_ENGINE = NODE_JS
|
||||
JS_ENGINES = [NODE_JS]
|
||||
'''
|
||||
|
||||
with open(dot_emscripten_path(), "w") as text_file: text_file.write(cfg)
|
||||
|
||||
# Clear old cached emscripten content.
|
||||
try:
|
||||
shutil.rmtree(os.path.expanduser("~/.emscripten_cache"), ignore_errors=True)
|
||||
os.remove(os.path.expanduser("~/.emscripten_sanity"))
|
||||
os.remove(os.path.expanduser("~/.emscripten_cache__last_clear"))
|
||||
except:
|
||||
pass
|
||||
|
||||
print "The following tool directories have been set for you in " + dot_emscripten_path() + ":"
|
||||
print ''
|
||||
print cfg
|
||||
|
||||
path_add = get_required_path(active_tools)
|
||||
print "To conveniently access the selected set of tools from the command line, consider adding the following directories to PATH, or call '" + os.path.relpath(sdk_path('emsdk_add_path')) + "' to do this for you."
|
||||
print ''
|
||||
if WINDOWS:
|
||||
print ' ' + ';'.join(path_add)
|
||||
else:
|
||||
print ' ' + ':'.join(path_add)
|
||||
|
||||
MSBUILD_DIR = "C:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/Platforms"
|
||||
|
||||
def get_installed_vstool_version(installed_path):
|
||||
try:
|
||||
return open(installed_path + "/version.txt", "r").read()
|
||||
except:
|
||||
return None
|
||||
|
||||
class Tool:
|
||||
def __init__(self, data):
|
||||
# Convert the dictionary representation of the tool in 'data' to members of this class for convenience.
|
||||
for key in data:
|
||||
setattr(self, key, data[key])
|
||||
|
||||
def __str__(self):
|
||||
s = self.id + '-' + self.version
|
||||
if hasattr(self, 'bitness'):
|
||||
s += '-' + str(self.bitness) + 'bit'
|
||||
return s
|
||||
|
||||
# Specifies the target path where this tool will be installed to. This could either be a directory or a filename (e.g. in case of node.js)
|
||||
def installation_path(self):
|
||||
if WINDOWS and hasattr(self, 'windows_install_path'):
|
||||
pth = self.windows_install_path.replace("%MSBuildPlatformsDir%", MSBUILD_DIR)
|
||||
return pth
|
||||
p = self.version
|
||||
if hasattr(self, 'bitness'):
|
||||
p += '_' + str(self.bitness) + 'bit'
|
||||
return os.path.join(self.id, p)
|
||||
|
||||
# Specifies the target directory this tool will be installed to.
|
||||
def installation_dir(self):
|
||||
dir = self.installation_path()
|
||||
if path_points_to_directory(dir):
|
||||
return dir
|
||||
else:
|
||||
return os.path.dirname(dir)
|
||||
|
||||
# Returns the configuration item that needs to be added to .emscripten to make this Tool active for the current user.
|
||||
def activated_config(self):
|
||||
if hasattr(self, 'activated_cfg'):
|
||||
tool_cfg = self.activated_cfg.replace('%installation_dir%', sdk_path(self.installation_dir()))
|
||||
tool_cfg = tool_cfg.replace('%.exe%', '.exe' if WINDOWS else '')
|
||||
return tool_cfg
|
||||
else:
|
||||
return ''
|
||||
|
||||
def is_installed(self):
|
||||
# If this tool/sdk depends on other tools, require that all dependencies are installed for this tool to count as being installed.
|
||||
if hasattr(self, 'uses'):
|
||||
for tool_name in self.uses:
|
||||
tool = find_tool(tool_name)
|
||||
if tool == None:
|
||||
print "Manifest error: No tool by name '" + tool_name + "' found! This may indicate an internal SDK error!"
|
||||
return False
|
||||
if not tool.is_installed():
|
||||
return False
|
||||
|
||||
if self.download_url() != None:
|
||||
content_exists = os.path.exists(self.installation_path()) and (os.path.isfile(self.installation_path()) or num_files_in_directory(self.installation_path()) > 0)
|
||||
|
||||
if self.id == 'vs-tool': # vs-tool is a special tool since all versions must be installed to the same dir, so dir name will not differentiate the version.
|
||||
return content_exists and get_installed_vstool_version(self.installation_path()) == self.version
|
||||
else:
|
||||
return content_exists
|
||||
else:
|
||||
return True # This tool does not contain downloadable elements, so it is installed by default.
|
||||
|
||||
def is_active(self):
|
||||
if not self.is_installed():
|
||||
return False
|
||||
|
||||
if self.id == 'vs-tool':
|
||||
return True # vs-tool is a special tool since all versions must be installed to the same dir, which means that if this tool is installed, it is also active.
|
||||
|
||||
# All dependencies of this tool must be active as well.
|
||||
deps = self.dependencies()
|
||||
for tool in deps:
|
||||
if not tool.is_active():
|
||||
return False
|
||||
|
||||
activated_cfg = self.activated_config()
|
||||
if activated_cfg == '':
|
||||
return len(deps) > 0
|
||||
|
||||
(key, value) = parse_key_value(activated_cfg)
|
||||
# print 'activated cfg ' + key + ', value: ' + value
|
||||
# if dot_emscripten.has_key(key):
|
||||
# print 'dot_emscripten ' + dot_emscripten[key]
|
||||
if dot_emscripten.has_key(key) and dot_emscripten[key] == value:
|
||||
return True
|
||||
return False
|
||||
|
||||
# If this tool can be installed on this system, this function returns True.
|
||||
# Otherwise, this function returns a string that describes the reason why this tool is not available.
|
||||
def can_be_installed(self):
|
||||
if self.id == 'vs-tool':
|
||||
if os.path.exists(MSBUILD_DIR):
|
||||
return True
|
||||
else:
|
||||
return "VS2010 was not found!"
|
||||
else:
|
||||
return True
|
||||
|
||||
def download_url(self):
|
||||
if WINDOWS and hasattr(self, 'windows_url'):
|
||||
return self.windows_url
|
||||
elif hasattr(self, 'url'):
|
||||
return self.url
|
||||
else:
|
||||
return None
|
||||
|
||||
def install(self):
|
||||
if self.can_be_installed() != True:
|
||||
print "The tool '" + str(self) + "' is not available due to the reason: " + self.can_be_installed()
|
||||
return False
|
||||
|
||||
print "Installing '" + str(self) + "'.."
|
||||
if self.id == 'sdk':
|
||||
for tool_name in self.uses:
|
||||
tool = find_tool(tool_name)
|
||||
if tool == None:
|
||||
print "Manifest error: No tool by name '" + tool_name + "' found! This may indicate an internal SDK error!"
|
||||
success = tool.install()
|
||||
if not success:
|
||||
return False
|
||||
else:
|
||||
url = self.download_url()
|
||||
if hasattr(self, 'git_branch'):
|
||||
success = git_clone_checkout_and_pull(url, self.installation_path(), self.git_branch)
|
||||
elif url.endswith('zip'):
|
||||
success = download_and_unzip(url, self.installation_path())
|
||||
else:
|
||||
success = download_file(emsdk_master_server + self.download_url(), self.installation_path())
|
||||
if not success:
|
||||
print "Installation failed!"
|
||||
return False
|
||||
print "Done."
|
||||
|
||||
# Sanity check that the installation succeeded.
|
||||
if not self.is_installed():
|
||||
print "Warning: The installation of '" + str(self) + "' seems to have failed, but no error was detected. Either something went wrong with the installation, or this may indicate an internal emsdk error."
|
||||
return True
|
||||
|
||||
def uninstall(self):
|
||||
if not self.is_installed():
|
||||
print "Tool '" + str(self) + "' was not installed. No need to uninstall."
|
||||
return
|
||||
print "Uninstalling tool '" + str(self) + "'.."
|
||||
try:
|
||||
print "Deleting path '" + self.installation_path() + "'"
|
||||
shutil.rmtree(self.installation_path(), ignore_errors=True)
|
||||
os.remove(self.installation_path())
|
||||
except:
|
||||
pass
|
||||
print "Done."
|
||||
|
||||
def dependencies(self):
|
||||
if not hasattr(self, 'uses'):
|
||||
return []
|
||||
deps = []
|
||||
|
||||
for tool_name in self.uses:
|
||||
tool = find_tool(tool_name)
|
||||
if tool:
|
||||
deps += [tool]
|
||||
return deps
|
||||
|
||||
def recursive_dependencies(self):
|
||||
if not hasattr(self, 'uses'):
|
||||
return []
|
||||
deps = []
|
||||
for tool_name in self.uses:
|
||||
tool = find_tool(tool_name)
|
||||
if tool:
|
||||
deps += [tool]
|
||||
deps += tool.recursive_dependencies()
|
||||
return deps
|
||||
|
||||
# A global registry of all known Emscripten SDK tools available in the SDK manifest.
|
||||
tools = []
|
||||
|
||||
# A global registry of all known SDK toolsets.
|
||||
sdks = []
|
||||
|
||||
# N.B. In both tools and sdks list above, we take the convention that the newest items are at the back of the list (ascending chronological order)
|
||||
|
||||
def find_tool(name):
|
||||
for tool in tools:
|
||||
if str(tool) == name:
|
||||
return tool
|
||||
return None
|
||||
|
||||
def find_sdk(name):
|
||||
for sdk in sdks:
|
||||
if str(sdk) == name:
|
||||
return sdk
|
||||
return None
|
||||
|
||||
def find_latest_sdk():
|
||||
return sdks[-1] # Newest SDK is always at the end of the list.
|
||||
|
||||
def update_emsdk():
|
||||
download_file(emsdk_master_server + 'emsdk_manifest.json', emsdk_path(), download_even_if_exists=True)
|
||||
download_file(emsdk_master_server + 'emsdk', emsdk_path(), download_even_if_exists=True)
|
||||
download_file(emsdk_master_server + 'README.txt', emsdk_path(), download_even_if_exists=True)
|
||||
print 'Update complete.'
|
||||
|
||||
def load_sdk_manifest():
|
||||
global tools
|
||||
manifest = json.loads(open(sdk_path("emsdk_manifest.json"), "r").read())
|
||||
for tool in manifest['tools']:
|
||||
tools.append(Tool(tool))
|
||||
|
||||
for sdk_str in manifest['sdks']:
|
||||
sdk = Tool(sdk_str)
|
||||
sdk.id = "sdk"
|
||||
sdks.append(sdk)
|
||||
|
||||
def install(): # TODO: Add parameter to choose which SDK to install.
|
||||
download_and_unzip('clang_3.2_32bit.zip', 'clang/3.2_32bit/')
|
||||
download_file(emsdk_master_server + 'node_0.10.17_32bit.exe', 'node/0.10.17_32bit/node.exe')
|
||||
download_and_unzip('python_2.7.5.1_32bit.zip', 'python/2.7.5.1_32bit/')
|
||||
download_and_unzip('git_1.8.3.zip', 'git/1.8.3/')
|
||||
#git_clone_checkout_and_pull(emscripten_git_repo, 'emscripten/', 'incoming')
|
||||
download_and_unzip('emscripten_1.5.6.zip', 'emscripten/1.5.6/')
|
||||
|
||||
def activate(sdk): # TODO: Add parameter to choose which SDK to activate.
|
||||
if not sdk.is_installed():
|
||||
print "The SDK/tool '" + str(sdk) + "' cannot be activated since it is not installed!"
|
||||
return
|
||||
tools_to_activate = [sdk] + sdk.recursive_dependencies()
|
||||
generate_dot_emscripten(tools_to_activate, temp_dir='temp')
|
||||
|
||||
def currently_active_sdk():
|
||||
for sdk in reversed(sdks):
|
||||
if sdk.is_active():
|
||||
return sdk
|
||||
return None
|
||||
|
||||
def main():
|
||||
load_dot_emscripten()
|
||||
load_sdk_manifest()
|
||||
usage_str = "usage: %prog --param1 .. --paramn <projectrootdir>"
|
||||
# parser = optparse.OptionParser(usage=usage_str)
|
||||
# parser.add_option('update', dest='update', action='store_true', default=False, help='Downloads and installs the latest Emscripten SDK components.')
|
||||
# (options, args) = parser.parse_args(sys.argv)
|
||||
if len(sys.argv) <= 1 or sys.argv[1] == 'help':
|
||||
if len(sys.argv) <= 1:
|
||||
print ' emsdk: No command given. Please call one of the following:'
|
||||
else:
|
||||
print ' emsdk: Available commands:'
|
||||
|
||||
print '''
|
||||
emsdk list - Lists all available SDKs and tools and their
|
||||
current installation status.
|
||||
|
||||
emsdk update - Fetches a list of updates from the net (but
|
||||
does not install them)
|
||||
|
||||
emsdk install <tool/sdk> - Downloads and installs the given tool or SDK.
|
||||
emsdk uninstall <tool/sdk> - Removes the given tool or SDK from disk.
|
||||
|
||||
emsdk activate <tool/sdk> - Activates the given tool or SDK as the
|
||||
default tool for the current user.
|
||||
|
||||
emsdk active_path [tool/sdk] - A helper command to report the directories
|
||||
that should be added to PATH to use the
|
||||
given tool or SDK. If no tool/sdk is
|
||||
specified, reports the directive for the
|
||||
currently active SDK. '''
|
||||
|
||||
if WINDOWS:
|
||||
print '''
|
||||
emcmdprompt.bat - Spawns a new command prompt that has the tool
|
||||
directories of all currently active tools
|
||||
added to PATH. '''
|
||||
return 1
|
||||
cmd = sys.argv[1]
|
||||
if cmd == 'list':
|
||||
print ''
|
||||
print 'The following individual tools exist:'
|
||||
for tool in tools:
|
||||
if tool.can_be_installed() == True:
|
||||
installed = '\tINSTALLED' if tool.is_installed() else ''
|
||||
else:
|
||||
installed = '\tNot available: ' + tool.can_be_installed()
|
||||
active = '*' if tool.is_active() else ' '
|
||||
print ' ' + active + ' {0: <25}'.format(str(tool)) + installed
|
||||
print ''
|
||||
print ''
|
||||
print 'The following Emscripten SDK versions are available:'
|
||||
for sdk in sdks:
|
||||
installed = '\tINSTALLED' if sdk.is_installed() else ''
|
||||
active = '*' if sdk.is_active() else ' '
|
||||
print ' ' + active + ' {0: <25}'.format(str(sdk)) + installed
|
||||
print ''
|
||||
print 'The items marked with * are activated for the current user.'
|
||||
return 0
|
||||
elif cmd == 'active_path':
|
||||
if len(sys.argv) <= 2:
|
||||
sdk = currently_active_sdk()
|
||||
if sdk == None:
|
||||
print "Missing tool/SDK name and no active SDK detected. Type 'emsdk active_path <tool/sdk name>' to query a list of directories that should be added to PATH to use the specified tool or SDK."
|
||||
return 1
|
||||
else:
|
||||
sys.argv += [str(sdk)]
|
||||
if sys.argv[2] == 'latest':
|
||||
sys.argv[2] = str(find_latest_sdk())
|
||||
tool = find_tool(sys.argv[2])
|
||||
if tool == None:
|
||||
tool = find_sdk(sys.argv[2])
|
||||
if tool == None:
|
||||
print "Error: No tool or SDK found by name '" + sys.argv[2] + "'."
|
||||
return 1
|
||||
tools_to_activate = [tool] + tool.recursive_dependencies()
|
||||
# These directories should be added to PATH
|
||||
path_add = get_required_path(tools_to_activate)
|
||||
# These already exist.
|
||||
existing_path = os.environ['PATH'].replace('\\', '/').split(';')
|
||||
new_path = [item for item in path_add if item not in existing_path]
|
||||
# print existing_path
|
||||
# print set(path_add)
|
||||
#uniq = list(set(existing_path) - set(path_add))
|
||||
#print uniq
|
||||
#new_path = path_add +
|
||||
print ';'.join(new_path)
|
||||
|
||||
return 0
|
||||
elif cmd == 'update':
|
||||
update_emsdk()
|
||||
return 0
|
||||
elif cmd == 'activate':
|
||||
if len(sys.argv) <= 2:
|
||||
print "Missing parameter. Type 'emsdk activate <tool name>' to install a tool or an SDK. Type 'emsdk list' to obtain a list of available tools. Type 'emsdk install latest' to automatically install the newest version of the SDK."
|
||||
return 1
|
||||
if sys.argv[2] == 'latest':
|
||||
sys.argv[2] = str(find_latest_sdk())
|
||||
tool = find_tool(sys.argv[2])
|
||||
if tool == None:
|
||||
tool = find_sdk(sys.argv[2])
|
||||
if tool == None:
|
||||
print "Error: No tool or SDK found by name '" + sys.argv[2] + "'."
|
||||
return 1
|
||||
activate(tool)
|
||||
return 0
|
||||
elif cmd == 'install':
|
||||
if len(sys.argv) <= 2:
|
||||
print "Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. Type 'emsdk list' to obtain a list of available tools. Type 'emsdk install latest' to automatically install the newest version of the SDK."
|
||||
return 1
|
||||
if sys.argv[2] == 'latest':
|
||||
sys.argv[2] = str(find_latest_sdk())
|
||||
tool = find_tool(sys.argv[2])
|
||||
if tool == None:
|
||||
tool = find_sdk(sys.argv[2])
|
||||
if tool == None:
|
||||
print "Error: No tool or SDK found by name '" + sys.argv[2] + "'."
|
||||
return 1
|
||||
tool.install()
|
||||
elif cmd == 'uninstall':
|
||||
if len(sys.argv) <= 2:
|
||||
print "Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools."
|
||||
return 1
|
||||
tool = find_tool(sys.argv[2])
|
||||
if tool == None:
|
||||
print "Error: Tool by name '" + sys.argv[2] + "' was not found."
|
||||
return 1
|
||||
tool.uninstall()
|
||||
else:
|
||||
print "Unknown command '" + cmd + "' given!"
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
26
emsdk_add_path.bat
Normal file
26
emsdk_add_path.bat
Normal file
@@ -0,0 +1,26 @@
|
||||
::This script looks up the set of currently activated emscripten tools, and adds all the necessary directories for each of them to PATH for the current command shell.
|
||||
@echo off
|
||||
|
||||
@call "%~dp0emsdk" active_path > nul 2> nul
|
||||
if ERRORLEVEL 1 goto error
|
||||
set ACTIVE_PATH=
|
||||
FOR /F "tokens=*" %%i in ('"%~dp0emsdk" active_path') do SET ACTIVE_PATH=%%i
|
||||
SET PATH=%ACTIVE_PATH%;%PATH%
|
||||
|
||||
::echo.
|
||||
::IF "%ACTIVE_PATH%" == "" (
|
||||
::echo No items needed to be added to PATH. Emscripten SDK is all set!
|
||||
::) ELSE (
|
||||
echo The following directories have been added to PATH:
|
||||
echo.
|
||||
echo PATH += %ACTIVE_PATH%
|
||||
::)
|
||||
|
||||
SET ACTIVE_PATH=
|
||||
goto end
|
||||
|
||||
:error
|
||||
echo Error: Cannot add tools to path: no active SDK detected! Activate an SDK first by typing 'emsdk activate [tool/sdk name]'.
|
||||
echo.
|
||||
|
||||
:end
|
||||
86
emsdk_manifest.json
Normal file
86
emsdk_manifest.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"id": "clang",
|
||||
"version": "3.2",
|
||||
"bitness": 32,
|
||||
"windows_url": "clang_3.2_32bit.zip",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_cfg": "LLVM_ROOT='%installation_dir%'"
|
||||
},
|
||||
{
|
||||
"id": "node",
|
||||
"version": "0.10.17",
|
||||
"bitness": 32,
|
||||
"windows_url": "node_0.10.17_32bit.exe",
|
||||
"windows_install_path": "node/0.10.17_32bit/node.exe",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_cfg": "NODE_JS='%installation_dir%/node.exe'"
|
||||
},
|
||||
{
|
||||
"id": "python",
|
||||
"version": "2.7.5.1",
|
||||
"bitness": 32,
|
||||
"windows_url": "python_2.7.5.1_32bit.zip",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_cfg": "PYTHON='%installation_dir%/python%.exe%'"
|
||||
},
|
||||
{
|
||||
"id": "git",
|
||||
"version": "1.8.3",
|
||||
"windows_url": "git_1.8.3.zip",
|
||||
"activated_path": "%installation_dir%/git/cmd",
|
||||
"activated_cfg": "EMSDK_GIT='%installation_dir%'"
|
||||
},
|
||||
{
|
||||
"id": "emscripten",
|
||||
"version": "1.5.6",
|
||||
"windows_url": "emscripten_1.5.6.zip",
|
||||
"activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_env": "EMSCRIPTEN=%installation_dir%"
|
||||
},
|
||||
{
|
||||
"id": "emscripten",
|
||||
"version": "incoming",
|
||||
"url": "git://github.com/kripken/emscripten.git",
|
||||
"git_branch": "incoming",
|
||||
"activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_env": "EMSCRIPTEN=%installation_dir%"
|
||||
},
|
||||
{
|
||||
"id": "emscripten",
|
||||
"version": "master",
|
||||
"url": "git://github.com/kripken/emscripten.git",
|
||||
"git_branch": "master",
|
||||
"activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
|
||||
"activated_path": "%installation_dir%",
|
||||
"activated_env": "EMSCRIPTEN=%installation_dir%"
|
||||
},
|
||||
{
|
||||
"id": "vs-tool",
|
||||
"version": "0.9.0",
|
||||
"windows_url": "vs-tool_0.9.0.zip",
|
||||
"windows_install_path": "%MSBuildPlatformsDir%/Emscripten"
|
||||
}
|
||||
],
|
||||
|
||||
"sdks": [
|
||||
{
|
||||
"version": "incoming",
|
||||
"bitness": 32,
|
||||
"uses": ["clang-3.2-32bit", "node-0.10.17-32bit", "python-2.7.5.1-32bit", "git-1.8.3", "emscripten-incoming"]
|
||||
},
|
||||
{
|
||||
"version": "master",
|
||||
"bitness": 32,
|
||||
"uses": ["clang-3.2-32bit", "node-0.10.17-32bit", "python-2.7.5.1-32bit", "git-1.8.3", "emscripten-master"]
|
||||
},
|
||||
{
|
||||
"version": "1.5.6",
|
||||
"bitness": 32,
|
||||
"uses": ["clang-3.2-32bit", "node-0.10.17-32bit", "python-2.7.5.1-32bit", "emscripten-1.5.6"]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user