module RbSys::Mkmf
def create_rust_makefile(target, &blk)
- Example: Configure a custom build profile -
Example: Basic -
def create_rust_makefile(target, &blk) if target.include?("/") target_prefix, target = File.split(target) target_prefix[0, 0] = "/" else target_prefix = "" end spec = Struct.new(:name, :metadata).new(target, {}) cargo_builder = CargoBuilder.new(spec) builder = Config.new(cargo_builder) yield builder if blk srcprefix = "$(srcdir)/#{builder.ext_dir}".chomp("/") RbConfig.expand(srcdir = srcprefix.dup) full_cargo_command = cargo_command(srcdir, builder) make_install = +<<~MAKE #{conditional_assign("RB_SYS_BUILD_DIR", File.join(Dir.pwd, ".rb-sys"))} #{conditional_assign("CARGO", "cargo")} #{conditional_assign("CARGO_BUILD_TARGET", builder.target)} #{conditional_assign("SOEXT", builder.so_ext)} # Determine the prefix Cargo uses for the lib. #{if_neq_stmt("$(SOEXT)", "dll")} #{conditional_assign("SOEXT_PREFIX", "lib", indent: 1)} #{endif_stmt} #{conditional_assign("RB_SYS_CARGO_PROFILE", builder.profile)} #{conditional_assign("RB_SYS_CARGO_FEATURES", builder.features.join(","))} #{conditional_assign("RB_SYS_EXTRA_RUSTFLAGS", builder.extra_rustflags.join(" "))} # Set dirname for the profile, since the profiles do not directly map to target dir (i.e. dev -> debug) #{if_eq_stmt("$(RB_SYS_CARGO_PROFILE)", "dev")} #{conditional_assign("RB_SYS_CARGO_PROFILE_DIR", "debug", indent: 1)} #{else_stmt} #{conditional_assign("RB_SYS_CARGO_PROFILE_DIR", "$(RB_SYS_CARGO_PROFILE)", indent: 1)} #{endif_stmt} # Set the build profile (dev, release, etc.) Compat with Rust 1.51. #{if_eq_stmt("$(RB_SYS_CARGO_PROFILE)", "release")} #{assign_stmt("RB_SYS_CARGO_PROFILE_FLAG", "--release", indent: 1)} #{else_stmt} #{assign_stmt("RB_SYS_CARGO_PROFILE_FLAG", "--profile $(RB_SYS_CARGO_PROFILE)", indent: 1)} #{endif_stmt} # Account for sub-directories when using `--target` argument with Cargo #{if_neq_stmt("$(CARGO_BUILD_TARGET)", "")} #{assign_stmt("RB_SYS_CARGO_BUILD_TARGET_DIR", "target/$(CARGO_BUILD_TARGET)", indent: 1)} #{else_stmt} #{assign_stmt("RB_SYS_CARGO_BUILD_TARGET_DIR", "target", indent: 1)} #{endif_stmt} target_prefix = #{target_prefix} TARGET_NAME = #{target[/\A\w+/]} TARGET_ENTRY = #{RbConfig::CONFIG["EXPORT_PREFIX"]}Init_$(TARGET_NAME) RUBYARCHDIR = $(sitearchdir)$(target_prefix) TARGET = #{target} DLLIB = $(TARGET).#{RbConfig::CONFIG["DLEXT"]} TARGET_DIR = #{Dir.pwd}/$(RB_SYS_CARGO_BUILD_TARGET_DIR)/$(RB_SYS_CARGO_PROFILE_DIR) RUSTLIB = $(TARGET_DIR)/$(SOEXT_PREFIX)$(TARGET_NAME).$(SOEXT) CLEANOBJS = $(TARGET_DIR)/.fingerprint $(TARGET_DIR)/incremental $(TARGET_DIR)/examples $(TARGET_DIR)/deps $(TARGET_DIR)/build $(TARGET_DIR)/.cargo-lock $(TARGET_DIR)/*.d $(TARGET_DIR)/*.rlib $(RB_SYS_BUILD_DIR) DEFFILE = $(TARGET_DIR)/$(TARGET)-$(arch).def CLEANLIBS = $(DLLIB) $(RUSTLIB) $(DEFFILE) #{base_makefile(srcdir)} #{if_neq_stmt("$(RB_SYS_VERBOSE)", "")} #{assign_stmt("Q", "$(0=@)", indent: 1)} #{endif_stmt} #{env_vars(builder)} #{export_env("RUSTFLAGS", "$(RUSTFLAGS) $(RB_SYS_EXTRA_RUSTFLAGS)")} FORCE: ; $(TARGET_DIR): \t$(ECHO) creating target directory \\($(@)\\) \t$(Q) $(MAKEDIRS) $(TARGET_DIR) $(DEFFILE): $(TARGET_DIR) \t$(ECHO) generating $(@) \t$(Q) ($(COPY) $(srcdir)/$(TARGET).def $@ 2> /dev/null) || (echo EXPORTS && echo $(TARGET_ENTRY)) > $@ #{optional_rust_toolchain(builder)} $(RUSTLIB): $(DEFFILE) FORCE \t$(ECHO) generating $(@) \\("$(RB_SYS_CARGO_PROFILE)"\\) \t$(Q) #{full_cargo_command} $(DLLIB): $(RUSTLIB) \t$(Q) $(COPY) "$(RUSTLIB)" $@ install-so: $(DLLIB) \t$(ECHO) installing $(DLLIB) to $(RUBYARCHDIR) \t$(Q) $(MAKEDIRS) $(RUBYARCHDIR) \t$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) install: #{builder.clean_after_install ? "install-so realclean" : "install-so"} all: #{$extout ? "install" : "$(DLLIB)"} MAKE gsub_cargo_command!(make_install, builder: builder) File.write("Makefile", make_install) end