summaryrefslogtreecommitdiff
path: root/defs/jit.mk
diff options
context:
space:
mode:
Diffstat (limited to 'defs/jit.mk')
-rw-r--r--defs/jit.mk61
1 files changed, 52 insertions, 9 deletions
diff --git a/defs/jit.mk b/defs/jit.mk
index 28d8f2da3a..2c1e819684 100644
--- a/defs/jit.mk
+++ b/defs/jit.mk
@@ -1,10 +1,9 @@
# Make recipes that deal with the rust code of YJIT and ZJIT.
-
-# Because of Cargo cache, if the actual binary is not changed from the
-# previous build, the mtime is preserved as the cached file.
-# This means the target is not updated actually, and it will need to
-# rebuild at the next build.
-RUST_LIB_TOUCH = touch $@
+#
+# $(gnumake_recursive) adds the '+' prefix to pass down GNU make's
+# jobserver resources to cargo/rustc as rust-lang.org recommends.
+# Without it, certain make version trigger a warning. It does not
+# add the prefix when `make --dry-run` so dry runs are indeed dry.
ifneq ($(JIT_CARGO_SUPPORT),no)
@@ -13,11 +12,17 @@ CARGO_VERBOSE_0 = -q
CARGO_VERBOSE_1 =
CARGO_VERBOSE = $(CARGO_VERBOSE_$(V))
+# Because of Cargo cache, if the actual binary is not changed from the
+# previous build, the mtime is preserved as the cached file.
+# This means the target is not updated actually, and it will need to
+# rebuild at the next build.
+RUST_LIB_TOUCH = touch $@
+
# NOTE: MACOSX_DEPLOYMENT_TARGET to match `rustc --print deployment-target` to avoid the warning below.
# ld: warning: object file (target/debug/libjit.a(<libcapstone object>)) was built for
# newer macOS version (15.2) than being linked (15.0)
# This limits us to an older set of macOS API in the rust code, but we don't use any.
-$(RUST_LIB): $(srcdir)/jit.rs
+$(RUST_LIB): $(srcdir)/ruby.rs target/.rustc-version
$(Q)if [ '$(ZJIT_SUPPORT)' != no -a '$(YJIT_SUPPORT)' != no ]; then \
echo 'building YJIT and ZJIT ($(JIT_CARGO_SUPPORT:yes=release) mode)'; \
elif [ '$(ZJIT_SUPPORT)' != no ]; then \
@@ -25,12 +30,39 @@ $(RUST_LIB): $(srcdir)/jit.rs
elif [ '$(YJIT_SUPPORT)' != no ]; then \
echo 'building YJIT ($(JIT_CARGO_SUPPORT) mode)'; \
fi
- +$(Q)CARGO_TARGET_DIR='$(CARGO_TARGET_DIR)' \
+ $(gnumake_recursive)$(Q)CARGO_TARGET_DIR='$(CARGO_TARGET_DIR)' \
CARGO_TERM_PROGRESS_WHEN='never' \
MACOSX_DEPLOYMENT_TARGET=11.0 \
$(CARGO) $(CARGO_VERBOSE) build --manifest-path '$(top_srcdir)/Cargo.toml' $(CARGO_BUILD_ARGS)
$(RUST_LIB_TOUCH)
-endif
+else ifneq ($(strip $(RLIB_DIR)),) # combo build
+
+$(RUST_LIB): $(srcdir)/ruby.rs target/.rustc-version
+ $(ECHO) 'building $(@F)'
+ $(gnumake_recursive)$(Q) $(RUSTC) --edition=2024 \
+ $(RUSTC_FLAGS) \
+ '-L$(@D)' \
+ --extern=yjit \
+ --extern=zjit \
+ --crate-type=staticlib \
+ --cfg 'feature="yjit"' \
+ --cfg 'feature="zjit"' \
+ '--out-dir=$(@D)' \
+ '$(top_srcdir)/ruby.rs'
+
+# Absolute path to avoid VPATH ambiguity
+JIT_RLIB = $(TOP_BUILD_DIR)/$(RLIB_DIR)/libjit.rlib
+$(YJIT_RLIB): $(JIT_RLIB)
+$(ZJIT_RLIB): $(JIT_RLIB)
+$(JIT_RLIB): target/.rustc-version
+ $(ECHO) 'building $(@F)'
+ $(gnumake_recursive)$(Q) $(RUSTC) --crate-name=jit \
+ --edition=2024 \
+ $(JIT_RUST_FLAGS) \
+ $(RUSTC_FLAGS) \
+ '--out-dir=$(@D)' \
+ '$(top_srcdir)/jit/src/lib.rs'
+endif # ifneq ($(JIT_CARGO_SUPPORT),no)
RUST_LIB_SYMBOLS = $(RUST_LIB:.a=).symbols
$(RUST_LIBOBJ): $(RUST_LIB)
@@ -45,6 +77,17 @@ endif
rust-libobj: $(RUST_LIBOBJ)
rust-lib: $(RUST_LIB)
+rustc-version-check: target/.rustc-version
+
+target/.rustc-version: PHONY
+ $(eval prev_version := $(if $(wildcard $@),$(shell cat $@)))
+ $(eval curr_version := $(shell $(RUSTC) -V | cut -d' ' -f2))
+ $(eval clean := $(filter-out $(prev_version),$(curr_version)))
+ $(if $(clean),$(ECHO) Cleaning $(@D) for rustc $(curr_version))
+ $(if $(clean),$(Q)$(RMALL) $(@D))
+ $(if $(clean),$(Q)$(MAKEDIRS) $(@D))
+ $(if $(clean),$(Q)echo $(curr_version) > $@)
+
# For Darwin only: a list of symbols that we want the glommed Rust static lib to export.
# Unfortunately, using wildcard like '_rb_*' with -exported-symbol does not work, at least
# not on version 820.1. Assume llvm-nm, so XCode 8.0 (from 2016) or newer.