diff --git a/components/servo/.cargo/config b/components/servo/.cargo/config index dffe440072c..1cea095353f 100644 --- a/components/servo/.cargo/config +++ b/components/servo/.cargo/config @@ -9,3 +9,6 @@ ar = "arm-linux-gnueabihf-ar" [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" ar = "aarch64-linux-gnu-ar" + +[target.'cfg(target_os=windows)'] +linker = "./fake-ld.cmd" \ No newline at end of file diff --git a/components/servo/fake-ld.cmd b/components/servo/fake-ld.cmd new file mode 100644 index 00000000000..b13c7e818ab --- /dev/null +++ b/components/servo/fake-ld.cmd @@ -0,0 +1,2 @@ +@echo off +gcc -mwindows %* diff --git a/etc/ci/upload_nightly.sh b/etc/ci/upload_nightly.sh index e3033cc0902..dfde162e354 100755 --- a/etc/ci/upload_nightly.sh +++ b/etc/ci/upload_nightly.sh @@ -41,8 +41,8 @@ main() { extension=dmg package=target/*."${extension}" elif [[ "${platform}" == "windows" ]]; then - extension=tar.gz - package=target/*."${extension}" + extension=msi + package=target/msi/*.msi else usage >&2 return 1 diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py index d3d7877c674..1bd91e6eae1 100644 --- a/python/servo/package_commands.py +++ b/python/servo/package_commands.py @@ -9,8 +9,11 @@ from __future__ import print_function, unicode_literals -import os +import sys import os.path as path +sys.path.append(path.join(path.dirname(sys.argv[0]), "components", "style", "properties", "Mako-0.9.1.zip")) + +import os import shutil import subprocess import tarfile @@ -24,7 +27,9 @@ from mach.decorators import ( Command, ) -from servo.command_base import CommandBase, cd, BuildNotFound, is_macosx +from mako.template import Template + +from servo.command_base import CommandBase, cd, BuildNotFound, is_macosx, is_windows from servo.post_build_commands import find_dep_path_newest @@ -42,6 +47,11 @@ def otool(s): yield l.split(' ', 1)[0][1:] +def listfiles(directory): + return [f for f in os.listdir(directory) + if path.isfile(path.join(directory, f))] + + def install_name_tool(old, new, binary): try: subprocess.check_call(['install_name_tool', '-change', old, '@executable_path/' + new, binary]) @@ -76,7 +86,7 @@ class PackageCommands(CommandBase): env["ANT_FLAVOR"] = "release" dev_flag = "" - target_dir = os.path.dirname(binary_path) + target_dir = path.dirname(binary_path) output_apk = "{}.apk".format(binary_path) try: with cd(path.join("support", "android", "build-apk")): @@ -91,7 +101,7 @@ class PackageCommands(CommandBase): dir_to_app = dir_to_dmg + '/Servo.app' dir_to_resources = dir_to_app + '/Contents/Resources/' dir_to_root = '/'.join(binary_path.split('/')[:-3]) - if os.path.exists(dir_to_dmg): + if path.exists(dir_to_dmg): print("Cleaning up from previous packaging") delete(dir_to_dmg) browserhtml_path = find_dep_path_newest('browserhtml', binary_path) @@ -123,7 +133,7 @@ class PackageCommands(CommandBase): continue need_relinked = set(otool(f)) new_path = dir_to_app + '/Contents/MacOS/' + f.split('/')[-1] - if not os.path.exists(new_path): + if not path.exists(new_path): shutil.copyfile(f, new_path) for dylib in need_relinked: if '/System/Library' in dylib or '/usr/lib' in dylib or 'servo' in dylib: @@ -153,6 +163,45 @@ class PackageCommands(CommandBase): print("Cleaning up") delete(dir_to_dmg) print("Packaged Servo into " + dmg_path) + elif is_windows(): + dir_to_package = path.dirname(binary_path) + dir_to_root = self.get_top_dir() + dir_to_msi = path.join(dir_to_package, 'msi') + if path.exists(dir_to_msi): + print("Cleaning up from previous packaging") + delete(dir_to_msi) + os.makedirs(dir_to_msi) + top_path = dir_to_root + browserhtml_path = find_dep_path_newest('browserhtml', binary_path) + if browserhtml_path is None: + print("Could not find browserhtml package; perhaps you haven't built Servo.") + return 1 + browserhtml_path = path.join(browserhtml_path, "out") + # generate Servo.wxs + template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako") + template = Template(open(template_path).read()) + wxs_path = path.join(dir_to_msi, "Servo.wxs") + open(wxs_path, "w").write(template.render( + exe_path=dir_to_package, + top_path=top_path, + browserhtml_path=browserhtml_path)) + # run candle and light + print("Creating MSI") + try: + with cd(dir_to_msi): + subprocess.check_call(['candle', wxs_path]) + except subprocess.CalledProcessError as e: + print("WiX candle exited with return value %d" % e.returncode) + return e.returncode + try: + wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0]) + with cd(dir_to_msi): + subprocess.check_call(['light', wxsobj_path]) + except subprocess.CalledProcessError as e: + print("WiX light exited with return value %d" % e.returncode) + return e.returncode + msi_path = path.join(dir_to_msi, "Servo.msi") + print("Packaged Servo into {}".format(msi_path)) else: dir_to_package = '/'.join(binary_path.split('/')[:-1]) dir_to_root = '/'.join(binary_path.split('/')[:-3]) diff --git a/resources/Servo.ico b/resources/Servo.ico new file mode 100644 index 00000000000..71d38a0c147 Binary files /dev/null and b/resources/Servo.ico differ diff --git a/support/windows/Servo.wxs.mako b/support/windows/Servo.wxs.mako new file mode 100644 index 00000000000..2532267758a --- /dev/null +++ b/support/windows/Servo.wxs.mako @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${include_directory(path.join(top_path, "resources"), "resources")} + ${include_directory(browserhtml_path, "browserhtml")} + + + + + + + + + + + + + + + + + + % for c in components: + + % endfor + + + + + + +<%! +import os +import os.path as path +import re +import uuid + +def make_id(s): + return "Id{}".format(s.replace("-", "_").replace("/", "_")) + +def listfiles(directory): + return [f for f in os.listdir(directory) + if path.isfile(path.join(directory, f))] + +def listdirs(directory): + return [f for f in os.listdir(directory) + if path.isdir(path.join(directory, f))] + +def windowize(p): + if not p.startswith("/"): + return p + return re.sub("^/([^/])+", "\\1:", p) + +components = [] +%> +<%def name="include_directory(d, n)"> + + + + <% components.append(make_id(path.basename(d))) %> + % for f in listfiles(d): + + % endfor + + + % for f in listdirs(d): + ${include_directory(path.join(d, f), f)} + % endfor + + diff --git a/support/windows/fonts.conf b/support/windows/fonts.conf new file mode 100644 index 00000000000..d43480eead5 --- /dev/null +++ b/support/windows/fonts.conf @@ -0,0 +1,44 @@ + + + + C:\Windows\Fonts + + + + mono + + + monospace + + + + + + + sans serif + + + sans-serif + + + + + + + sans + + + sans-serif + + + + + + ~/.fontconfig +