feat: vendor GYP and libuv dependencies directly into repository for offline builds
Remove dynamic dependency download during build by checking in libuv source and GYP build tooling. Update .gitignore to exclude intermediate build artifacts from the vendored deps directory, adjust Makefile to remove the now-unnecessary cleanall target and deps folder cleanup, and add the full libuv project tree including its own .gitignore, .mailmap, AUTHORS, CONTRIBUTING.md, ChangeLog, and LICENSE files.
This commit is contained in:
Executable
+93
@@ -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)
|
||||
-188
@@ -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()
|
||||
Executable
+73
@@ -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)
|
||||
@@ -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)
|
||||
+3
-6
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user