summaryrefslogtreecommitdiff
path: root/defs/jit.mk
blob: 42b56c4cd928b6689bdcda2418fca0b18fe6adb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Make recipes that deal with the rust code of YJIT and ZJIT.
#
# $(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)

# Show Cargo progress when doing `make V=1`
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)/ruby.rs
	$(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 \
	    echo 'building ZJIT ($(JIT_CARGO_SUPPORT) mode)'; \
	elif [ '$(YJIT_SUPPORT)' != no ]; then \
	    echo 'building YJIT ($(JIT_CARGO_SUPPORT) mode)'; \
	fi
	$(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)
else ifneq ($(strip $(RLIB_DIR)),) # combo build

$(RUST_LIB): $(srcdir)/ruby.rs
	$(ECHO) 'building $(@F)'
	$(gnumake_recursive)$(Q) $(RUSTC) --edition=2024 \
	    '-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):
	$(ECHO) 'building $(@F)'
	$(gnumake_recursive)$(Q) $(RUSTC) --crate-name=jit \
	    --edition=2024 \
	    $(JIT_RUST_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)
	$(ECHO) 'partial linking $(RUST_LIB) into $@'
ifneq ($(findstring darwin,$(target_os)),)
	$(Q) $(CC) -nodefaultlibs -r -o $@ -exported_symbols_list $(RUST_LIB_SYMBOLS) $(RUST_LIB)
else
	$(Q) $(LD) -r -o $@ --whole-archive $(RUST_LIB)
	-$(Q) $(OBJCOPY) --wildcard --keep-global-symbol='$(SYMBOL_PREFIX)rb_*' $(@)
endif

rust-libobj: $(RUST_LIBOBJ)
rust-lib: $(RUST_LIB)

# 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.
#
# The -exported_symbols_list pulls out the right archive members. Symbols not listed
# in the list are made private extern, which are in turn made local as we're using `ld -r`.
# Note, section about -keep_private_externs in ld's man page hints at this behavior on which
# we rely.
ifneq ($(findstring darwin,$(target_os)),)
$(RUST_LIB_SYMBOLS): $(RUST_LIB)
	$(Q) $(tooldir)/darwin-ar $(NM) --defined-only --extern-only $(RUST_LIB) | \
	sed -n -e 's/.* //' -e '/^$(SYMBOL_PREFIX)rb_/p' \
	-e '/^$(SYMBOL_PREFIX)rust_eh_personality/p' \
	> $@

$(RUST_LIBOBJ): $(RUST_LIB_SYMBOLS)
endif