diff --git a/.gitignore b/.gitignore index 9f111ebc..d996ca57 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ wren # Intermediate files. build/ +deps/ .sass-cache/ # I leave a temporary Wren script at the top level so that I can quickly test diff --git a/Makefile b/Makefile index 40c2bb68..7814c8df 100644 --- a/Makefile +++ b/Makefile @@ -4,18 +4,16 @@ # Executables are built to bin/. Libraries are built to lib/. -LIBUV := build/libuv/out/Release/libuv.a - # A normal, optimized release build for the current CPU architecture. -release: $(LIBUV) +release: @ $(MAKE) -f script/wren.mk @ cp bin/wren wren # For convenience, copy the interpreter to the top level. # A debug build for the current architecture. -debug: $(LIBUV) +debug: @ $(MAKE) -f script/wren.mk MODE=debug -# A release build of just the VM. Does not require libuv. +# A release build of just the VM. vm: @ $(MAKE) -f script/wren.mk vm @@ -32,16 +30,17 @@ all: debug release @ $(MAKE) -f script/wren.mk MODE=debug ARCH=64 @ $(MAKE) -f script/wren.mk MODE=debug LANG=cpp ARCH=64 -# Download and build libuv to a static library. -$(LIBUV): script/libuv.py - @ ./script/libuv.py - -# Remove all build outputs and intermediate files. +# Remove all build outputs and intermediate files. Does not remove downloaded +# dependencies. Use cleanall for that. clean: @ rm -rf bin @ rm -rf build @ rm -rf lib +# Remove all build outputs, intermediate files, and downloaded dependencies. +cleanall: clean + @ rm -rf deps + # Run the tests against the debug build of Wren. test: debug @ $(MAKE) -f script/wren.mk MODE=debug test diff --git a/script/libuv.py b/script/libuv.py index 17aa8693..e95e6913 100755 --- a/script/libuv.py +++ b/script/libuv.py @@ -12,7 +12,7 @@ import subprocess import sys LIB_UV_VERSION = "v1.6.1" -LIB_UV_DIR = "build/libuv" +LIB_UV_DIR = "deps/libuv" def ensure_dir(dir): """Creates dir if not already there.""" @@ -22,6 +22,7 @@ def ensure_dir(dir): os.makedirs(dir) + def remove_dir(dir): """Recursively removes dir.""" @@ -31,10 +32,11 @@ def remove_dir(dir): subprocess.check_call( ['cmd', '/c', 'rd', '/s', '/q', dir.replace('/', '\\')]) else: - shutil.rmtree(LIB_UV_DIR) + shutil.rmtree(dir) + def download_libuv(): - """Clones libuv into build/libuv and checks out the right version.""" + """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. @@ -42,7 +44,7 @@ def download_libuv(): print("Cleaning output directory...") remove_dir(LIB_UV_DIR) - ensure_dir("build") + ensure_dir("deps") print("Cloning libuv...") run([ @@ -90,7 +92,7 @@ def build_libuv_mac(): ]) -def build_libuv_linux(): +def build_libuv_linux(arch): run(["python", "gyp_uv.py", "-f", "make"], cwd=LIB_UV_DIR) run(["make", "-C", "out", "BUILDTYPE=Release"], cwd=LIB_UV_DIR) @@ -99,17 +101,24 @@ def build_libuv_windows(): run(["cmd", "/c", "vcbuild.bat", "release"], cwd=LIB_UV_DIR) -def build_libuv(): +def build_libuv(arch, out): if platform.system() == "Darwin": build_libuv_mac() elif platform.system() == "Linux": - build_libuv_linux() - elif platform.system() == "Windows": + build_libuv_linux(arch) + elif platform.system(arch) == "Windows": build_libuv_windows() 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.""" @@ -117,8 +126,29 @@ def run(args, cwd=None): def main(): - download_libuv() - build_libuv() + 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() diff --git a/script/wren.mk b/script/wren.mk index af7c2a30..2feb61cd 100644 --- a/script/wren.mk +++ b/script/wren.mk @@ -60,12 +60,14 @@ ifeq ($(ARCH),32) C_OPTIONS += -m32 WREN := $(WREN)-32 BUILD_DIR := $(BUILD_DIR)-32 + LIBUV_ARCH := -32 endif ifeq ($(ARCH),64) C_OPTIONS += -m64 WREN := $(WREN)-64 BUILD_DIR := $(BUILD_DIR)-64 + LIBUV_ARCH := -64 endif # Some platform-specific workarounds. Note that we use "gcc" explicitly in the @@ -107,8 +109,8 @@ MODULE_OBJECTS := $(addprefix $(BUILD_DIR)/module/, $(notdir $(MODULE_SOURCES:.c VM_OBJECTS := $(addprefix $(BUILD_DIR)/vm/, $(notdir $(VM_SOURCES:.c=.o))) TEST_OBJECTS := $(patsubst test/api/%.c, $(BUILD_DIR)/test/%.o, $(TEST_SOURCES)) -LIBUV_DIR := build/libuv -LIBUV := $(LIBUV_DIR)/out/Release/libuv.a +LIBUV_DIR := deps/libuv +LIBUV := build/libuv$(LIBUV_ARCH).a # Flags needed to compile source files for the CLI, including the modules and # API tests. @@ -131,51 +133,61 @@ test: $(BUILD_DIR)/test/$(WREN) # Command-line interpreter. bin/$(WREN): $(CLI_OBJECTS) $(MODULE_OBJECTS) $(VM_OBJECTS) $(LIBUV) - @printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)" - @mkdir -p bin - @$(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS) + @ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)" + @ mkdir -p bin + @ $(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS) # Static library. lib/lib$(WREN).a: $(VM_OBJECTS) - @printf "%10s %-30s %s\n" $(AR) $@ "rcu" - @mkdir -p lib - @$(AR) rcu $@ $^ + @ printf "%10s %-30s %s\n" $(AR) $@ "rcu" + @ mkdir -p lib + @ $(AR) rcu $@ $^ # Shared library. lib/lib$(WREN).$(SHARED_EXT): $(VM_OBJECTS) - @printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS) $(SHARED_LIB_FLAGS)" - @mkdir -p lib - @$(CC) $(CFLAGS) -shared $(SHARED_LIB_FLAGS) -o $@ $^ + @ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS) $(SHARED_LIB_FLAGS)" + @ mkdir -p lib + @ $(CC) $(CFLAGS) -shared $(SHARED_LIB_FLAGS) -o $@ $^ # Test executable. $(BUILD_DIR)/test/$(WREN): $(TEST_OBJECTS) $(MODULE_OBJECTS) $(VM_OBJECTS) \ $(BUILD_DIR)/cli/io.o $(BUILD_DIR)/cli/vm.o $(LIBUV) - @printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)" - @mkdir -p $(BUILD_DIR)/test - @$(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS) + @ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)" + @ mkdir -p $(BUILD_DIR)/test + @ $(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS) # CLI object files. -$(BUILD_DIR)/cli/%.o: src/cli/%.c $(CLI_HEADERS) $(MODULE_HEADERS) $(VM_HEADERS) - @printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" - @mkdir -p $(BUILD_DIR)/cli - @$(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< +$(BUILD_DIR)/cli/%.o: src/cli/%.c $(CLI_HEADERS) $(MODULE_HEADERS) \ + $(VM_HEADERS) $(LIBUV) + @ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" + @ mkdir -p $(BUILD_DIR)/cli + @ $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< # Module object files. -$(BUILD_DIR)/module/%.o: src/module/%.c $(CLI_HEADERS) $(MODULE_HEADERS) $(VM_HEADERS) - @printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" - @mkdir -p $(BUILD_DIR)/module - @$(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< +$(BUILD_DIR)/module/%.o: src/module/%.c $(CLI_HEADERS) $(MODULE_HEADERS) \ + $(VM_HEADERS) $(LIBUV) + @ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" + @ mkdir -p $(BUILD_DIR)/module + @ $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< # VM object files. $(BUILD_DIR)/vm/%.o: src/vm/%.c $(VM_HEADERS) - @printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" - @mkdir -p $(BUILD_DIR)/vm - @$(CC) -c $(CFLAGS) -Isrc/include -o $@ $(FILE_FLAG) $< + @ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" + @ mkdir -p $(BUILD_DIR)/vm + @ $(CC) -c $(CFLAGS) -Isrc/include -o $@ $(FILE_FLAG) $< # Test object files. -$(BUILD_DIR)/test/%.o: test/api/%.c $(MODULE_HEADERS) $(VM_HEADERS) - @printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" - @mkdir -p $(dir $@) - @$(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< +$(BUILD_DIR)/test/%.o: test/api/%.c $(MODULE_HEADERS) $(VM_HEADERS) $(LIBUV) + @ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" + @ mkdir -p $(dir $@) + @ $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< + +# Download libuv. +$(LIBUV_DIR)/build/gyp/gyp: script/libuv.py + @ ./script/libuv.py download + +# Build libuv to a static library. +$(LIBUV): $(LIBUV_DIR)/build/gyp/gyp script/libuv.py + @ ./script/libuv.py build $(LIBUV_ARCH) .PHONY: all cli test vm diff --git a/test/benchmark/delta_blue.wren b/test/benchmark/delta_blue.wren index 4c88d6db..af57d8a2 100644 --- a/test/benchmark/delta_blue.wren +++ b/test/benchmark/delta_blue.wren @@ -708,4 +708,3 @@ for (i in 0...20) { IO.print(total) IO.print("elapsed: ", IO.clock - start) -