1
0
forked from Mirror/wren

Vendor GYP and libuv into the repo.

Instead of dynamically downloading these as needed during a build, this
checks in those two dependencies directly into the Wren repo. That's a
little lame because users of Wren who aren't building the CLI don't
actually need them, but they aren't too big, so it's not a huge deal.

It makes builds (particularly on Travis) more reliable, because they
don't have to pull down additional content over the network.
This commit is contained in:
Bob Nystrom
2017-04-09 09:31:44 -07:00
parent 3ce9ecfc65
commit f866ee7003
184 changed files with 83315 additions and 208 deletions

93
util/build_libuv.py Executable file
View File

@ -0,0 +1,93 @@
#!/usr/bin/env python
# Runs GYP to generate the right project then uses that to build libuv.
from __future__ import print_function
import os
import platform
import shutil
import sys
from util import ensure_dir, python2_binary, run
LIB_UV_VERSION = "v1.10.0"
LIB_UV_DIR = "deps/libuv"
def build_libuv_mac():
# Create the XCode project.
run([
python2_binary(), LIB_UV_DIR + "/gyp_uv.py", "-f", "xcode"
])
# Compile it.
# TODO: Support debug builds too.
run([
"xcodebuild",
# Build a 32-bit + 64-bit universal binary:
"ARCHS=i386 x86_64", "ONLY_ACTIVE_ARCH=NO",
"BUILD_DIR=out",
"-project", LIB_UV_DIR + "/uv.xcodeproj",
"-configuration", "Release",
"-target", "libuv"
])
def build_libuv_linux(arch):
# Set up the Makefile to build for the right architecture.
args = [python2_binary(), "gyp_uv.py", "-f", "make"]
if arch == "-32":
args.append("-Dtarget_arch=ia32")
elif arch == "-64":
args.append("-Dtarget_arch=x64")
run(args, cwd=LIB_UV_DIR)
run(["make", "-C", "out", "BUILDTYPE=Release"], cwd=LIB_UV_DIR)
def build_libuv_windows(arch):
args = ["cmd", "/c", "vcbuild.bat", "release"]
if arch == "-32":
args.append("x86")
elif arch == "-64":
args.append("x64")
run(args, cwd=LIB_UV_DIR)
def build_libuv(arch, out):
if platform.system() == "Darwin":
build_libuv_mac()
elif platform.system() == "Linux":
build_libuv_linux(arch)
elif platform.system() == "Windows":
build_libuv_windows(arch)
else:
print("Unsupported platform: " + platform.system())
sys.exit(1)
# Copy the build library to the build directory for Mac and Linux where we
# support building for multiple architectures.
if platform.system() != "Windows":
ensure_dir(os.path.dirname(out))
shutil.copyfile(
os.path.join(LIB_UV_DIR, "out", "Release", "libuv.a"), out)
def main(args):
expect_usage(len(args) >= 1 and len(args) <= 2)
arch = "" if len(args) < 2 else args[2]
out = os.path.join("build", "libuv" + arch + ".a")
build_libuv(arch, out)
def expect_usage(condition):
if (condition): return
print("Usage: build_libuv.py [-32|-64]")
sys.exit(1)
main(sys.argv)

View File

@ -1,188 +0,0 @@
#!/usr/bin/env python
# Downloads and compiles libuv.
from __future__ import print_function
import os
import os.path
import platform
import shutil
import subprocess
import sys
LIB_UV_VERSION = "v1.10.0"
LIB_UV_DIR = "deps/libuv"
def python2_binary():
"""Tries to find a python 2 executable."""
# Using [0] instead of .major here to support Python 2.6.
if sys.version_info[0] == 2:
return sys.executable or "python"
else:
return "python2"
def ensure_dir(dir):
"""Creates dir if not already there."""
if os.path.isdir(dir):
return
os.makedirs(dir)
def remove_dir(dir):
"""Recursively removes dir."""
if platform.system() == "Windows":
# rmtree gives up on readonly files on Windows
# rd doesn't like paths with forward slashes
subprocess.check_call(
['cmd', '/c', 'rd', '/s', '/q', dir.replace('/', '\\')])
else:
shutil.rmtree(dir)
def download_libuv():
"""Clones libuv into deps/libuv and checks out the right version."""
# Delete it if already there so we ensure we get the correct version if the
# version number in this script changes.
if os.path.isdir(LIB_UV_DIR):
print("Cleaning output directory...")
remove_dir(LIB_UV_DIR)
ensure_dir("deps")
print("Cloning libuv...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://github.com/libuv/libuv.git",
LIB_UV_DIR
])
print("Getting tags...")
run([
"git", "fetch", "--quiet", "--depth=1", "--tags"
], cwd=LIB_UV_DIR)
print("Checking out libuv " + LIB_UV_VERSION + "...")
run([
"git", "checkout", "--quiet", LIB_UV_VERSION
], cwd=LIB_UV_DIR)
# TODO: Pin gyp to a known-good commit. Update a previously downloaded gyp
# if it doesn't match that commit.
print("Downloading gyp...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://chromium.googlesource.com/external/gyp.git",
LIB_UV_DIR + "/build/gyp"
])
def build_libuv_mac():
# Create the XCode project.
run([
python2_binary(), LIB_UV_DIR + "/gyp_uv.py", "-f", "xcode"
])
# Compile it.
# TODO: Support debug builds too.
run([
"xcodebuild",
# Build a 32-bit + 64-bit universal binary:
"ARCHS=i386 x86_64", "ONLY_ACTIVE_ARCH=NO",
"BUILD_DIR=out",
"-project", LIB_UV_DIR + "/uv.xcodeproj",
"-configuration", "Release",
"-target", "All"
])
def build_libuv_linux(arch):
# Set up the Makefile to build for the right architecture.
args = [python2_binary(), "gyp_uv.py", "-f", "make"]
if arch == "-32":
args.append("-Dtarget_arch=ia32")
elif arch == "-64":
args.append("-Dtarget_arch=x64")
run(args, cwd=LIB_UV_DIR)
run(["make", "-C", "out", "BUILDTYPE=Release"], cwd=LIB_UV_DIR)
def build_libuv_windows(arch):
args = ["cmd", "/c", "vcbuild.bat", "release"]
if arch == "-32":
args.append("x86")
elif arch == "-64":
args.append("x64")
run(args, cwd=LIB_UV_DIR)
def build_libuv(arch, out):
if platform.system() == "Darwin":
build_libuv_mac()
elif platform.system() == "Linux":
build_libuv_linux(arch)
elif platform.system() == "Windows":
build_libuv_windows(arch)
else:
print("Unsupported platform: " + platform.system())
sys.exit(1)
# Copy the build library to the build directory for Mac and Linux where we
# support building for multiple architectures.
if platform.system() != "Windows":
ensure_dir(os.path.dirname(out))
shutil.copyfile(
os.path.join(LIB_UV_DIR, "out", "Release", "libuv.a"), out)
def run(args, cwd=None):
"""Spawn a process to invoke [args] and mute its output."""
try:
# check_output() was added in Python 2.7.
has_check_output = (sys.version_info[0] > 2 or
(sys.version_info[0] == 2 and sys.version_info[1] >= 7))
if has_check_output:
subprocess.check_output(args, cwd=cwd, stderr=subprocess.STDOUT)
else:
proc = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE)
proc.communicate()[0].split()
except subprocess.CalledProcessError as error:
print(error.output)
sys.exit(error.returncode)
def main():
expect_usage(len(sys.argv) >= 2)
if sys.argv[1] == "download":
download_libuv()
elif sys.argv[1] == "build":
expect_usage(len(sys.argv) <= 3)
arch = ""
if len(sys.argv) == 3:
arch = sys.argv[2]
out = os.path.join("build", "libuv" + arch + ".a")
build_libuv(arch, out)
else:
expect_usage(false)
def expect_usage(condition):
if (condition): return
print("Usage: libuv.py download")
print(" libuv.py build [-32|-64]")
sys.exit(1)
main()

73
util/update_deps.py Executable file
View File

@ -0,0 +1,73 @@
#!/usr/bin/env python
# Downloads GYP and libuv into deps/.
#
# Run this manually to update the vendored copies of GYP and libuv that are
# committed in the Wren repo.
from __future__ import print_function
import sys
from util import clean_dir, remove_dir, replace_in_file, run
LIB_UV_VERSION = "v1.10.0"
LIB_UV_DIR = "deps/libuv"
def main(args):
# Delete it if already there so we ensure we get the correct version if the
# version number in this script changes.
clean_dir("deps")
print("Cloning libuv...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://github.com/libuv/libuv.git",
LIB_UV_DIR
])
print("Getting tags...")
run([
"git", "fetch", "--quiet", "--depth=1", "--tags"
], cwd=LIB_UV_DIR)
print("Checking out libuv " + LIB_UV_VERSION + "...")
run([
"git", "checkout", "--quiet", LIB_UV_VERSION
], cwd=LIB_UV_DIR)
# TODO: Pin gyp to a known-good commit. Update a previously downloaded gyp
# if it doesn't match that commit.
print("Downloading gyp...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://chromium.googlesource.com/external/gyp.git",
LIB_UV_DIR + "/build/gyp"
])
# We don't need all of libuv and gyp's various support files.
print("Deleting unneeded files...")
remove_dir("deps/libuv/build/gyp/buildbot")
remove_dir("deps/libuv/build/gyp/infra")
remove_dir("deps/libuv/build/gyp/samples")
remove_dir("deps/libuv/build/gyp/test")
remove_dir("deps/libuv/build/gyp/tools")
remove_dir("deps/libuv/docs")
remove_dir("deps/libuv/img")
remove_dir("deps/libuv/samples")
remove_dir("deps/libuv/test")
# We are going to commit libuv and GYP in the main Wren repo, so we don't
# want them to be their own repos.
remove_dir("deps/libuv/.git")
remove_dir("deps/libuv/build/gyp/.git")
# Libuv's .gitignore ignores GYP, but we want to commit it.
replace_in_file("deps/libuv/.gitignore",
"/build/gyp",
"# /build/gyp (We do want to commit GYP in Wren's repo)")
main(sys.argv)

77
util/util.py Normal file
View File

@ -0,0 +1,77 @@
# Utility functions used by other Python files in this directory.
from __future__ import print_function
import os
import os.path
import platform
import shutil
import subprocess
import sys
def python2_binary():
"""Tries to find a python 2 executable."""
# Using [0] instead of .major here to support Python 2.6.
if sys.version_info[0] == 2:
return sys.executable or "python"
else:
return "python2"
def clean_dir(dir):
"""If dir exists, deletes it and recreates it, otherwise creates it."""
if os.path.isdir(dir):
remove_dir(dir)
os.makedirs(dir)
def ensure_dir(dir):
"""Creates dir if not already there."""
if os.path.isdir(dir):
return
os.makedirs(dir)
def remove_dir(dir):
"""Recursively removes dir."""
if platform.system() == "Windows":
# rmtree gives up on readonly files on Windows
# rd doesn't like paths with forward slashes
subprocess.check_call(
['cmd', '/c', 'rd', '/s', '/q', dir.replace('/', '\\')])
else:
shutil.rmtree(dir)
def replace_in_file(path, text, replace):
"""Replaces all occurrences of `text` in the file at `path` with `replace`."""
with open(path) as file:
contents = file.read()
contents = contents.replace(text, replace)
with open(path, "w") as file:
file.write(contents)
def run(args, cwd=None):
"""Spawn a process to invoke [args] and mute its output."""
try:
# check_output() was added in Python 2.7.
has_check_output = (sys.version_info[0] > 2 or
(sys.version_info[0] == 2 and sys.version_info[1] >= 7))
if has_check_output:
subprocess.check_output(args, cwd=cwd, stderr=subprocess.STDOUT)
else:
proc = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE)
proc.communicate()[0].split()
except subprocess.CalledProcessError as error:
print(error.output)
sys.exit(error.returncode)

View File

@ -213,13 +213,10 @@ $(BUILD_DIR)/test/%.o: test/api/%.c $(OPT_HEADERS) $(MODULE_HEADERS) \
$(V) mkdir -p $(dir $@)
$(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $<
# Download libuv.
$(LIBUV_DIR)/build/gyp/gyp: util/libuv.py
$(V) ./util/libuv.py download
# Build libuv to a static library.
$(LIBUV): $(LIBUV_DIR)/build/gyp/gyp util/libuv.py
$(V) ./util/libuv.py build $(LIBUV_ARCH)
$(LIBUV): $(LIBUV_DIR)/build/gyp/gyp util/update_deps.py
@ printf "%10s %-30s %s\n" run util/build_libuv.py
$(V) ./util/build_libuv.py $(LIBUV_ARCH)
# Wren modules that get compiled into the binary as C strings.
src/optional/wren_opt_%.wren.inc: src/optional/wren_opt_%.wren util/wren_to_c_string.py