2026-10-25 20:51 UTC
Replies (1)
-
@urushitan@kakera.kintsugi.moe 2026-10-26 00:10
ok a makefile is basically a script runner like this. the c/c++ compiler doesn’t touch the makefile, that’s a separate tool insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o``` for a rust program, you might have a cargo.toml like ```[package] name = "jsontool" version = "0.1.0" edition = "2021" [dependencies] anyhow = "1" clap = { version = "4", features = ["derive"] } serde = { version = "1", features = ["derive"] } serde_json = "1" [profile.release] lto = true``` and .cargo/config.toml like (for the local distro config, no internet packages) ```[source.crates-io] replace-with = "distro" [source.distro] directory = "/usr/share/cargo/registry" # or: registry = "sparse+https://crates.internal.example/index/" [net] offline = true``` If you wanted that same functionality from a makefile for rust it would be something like ```# Makefile: build jsontool with plain rustc, no cargo. RUSTC ?= rustc REG := /usr/share/cargo/registry OUT := $(abspath build) HOST := $(shell $(RUSTC) -vV | sed -n 's/^host: //p') FLAGS := -C opt-level=3 --cap-lints=allow -L dependency=$(OUT) --out-dir $(OUT) ext = $(foreach c,$(1),--extern $(c)=$(OUT)/lib$(c).rlib) extpm = $(foreach c,$(1),--extern $(c)=$(OUT)/lib$(c).so) # Pinned by hand. Cargo.lock does this for you; here, a distro upgrade # renames these directories and the build breaks. UNICODE_IDENT := $(REG)/unicode-ident-1.0.13 PROC_MACRO2 := $(REG)/proc-macro2-1.0.89 QUOTE := $(REG)/quote-1.0.37 SYN := $(REG)/syn-2.0.85 SERDE_DERIVE := $(REG)/serde_derive-1.0.213 # ... ~20 more ... # ---- 1. Plain library crate ---- # Edition, crate name (hyphens -> underscores), and features all come from # reading each crate's Cargo.toml yourself. $(OUT)/libunicode_ident.rlib: $(RUSTC) --edition=2018 --crate-type=lib --crate-name unicode_ident \ $(FLAGS) $(UNICODE_IDENT)/src/lib.rs # ---- 2. Crate with a build.rs: compile it, run it with the env vars cargo # would set, then scrape its stdout for cfg flags ---- $(OUT)/proc_macro2.cfg: mkdir -p $(OUT)/bs-pm2 $(RUSTC) --edition=2021 --crate-type=bin $(PROC_MACRO2)/build.rs \ -o $(OUT)/bs-pm2/build-script cd $(PROC_MACRO2) && env OUT_DIR=$(OUT)/bs-pm2 RUSTC=$(RUSTC) \ TARGET=$(HOST) HOST=$(HOST) PROFILE=release OPT_LEVEL=3 \ CARGO_MANIFEST_DIR=$(PROC_MACRO2) CARGO_PKG_VERSION=1.0.89 \ CARGO_FEATURE_DEFAULT=1 CARGO_FEATURE_PROC_MACRO=1 \ CARGO_CFG_TARGET_OS=linux CARGO_CFG_TARGET_ARCH=x86_64 \ $(OUT)/bs-pm2/build-script \ | sed -n 's/^cargo::\?rustc-cfg=\(.*\)/--cfg=\1/p' > $@ $(OUT)/libproc_macro2.rlib: $(OUT)/proc_macro2.cfg $(OUT)/libunicode_ident.rlib $(RUSTC) --edition=2021 --crate-type=lib --crate-name proc_macro2 $(FLAGS) \ --cfg 'feature="default"' --cfg 'feature="proc-macro"' \ $$(cat $<) $(call ext,unicode_ident) $(PROC_MACRO2)/src/lib.rs # ---- 3. Proc-macro crate: different crate type, must be built for the # HOST (matters when cross-compiling), linked as a .so ---- # syn's feature list must be the UNION of what serde_derive AND clap_derive # need. Cargo computes this (feature unification); here you work it out by hand. $(OUT)/libserde_derive.so: $(OUT)/libproc_macro2.rlib $(OUT)/libquote.rlib $(OUT)/libsyn.rlib $(RUSTC) --edition=2015 --crate-type=proc-macro --crate-name serde_derive \ $(FLAGS) --cfg 'feature="default"' \ $(call ext,proc_macro2 quote syn) $(SERDE_DERIVE)/src/lib.rs # ... ~20 more rules like the above (serde, serde_json, anyhow, and # clap_* each have their own quirks, and several have build.rs) ... # ---- Finally, your program ---- # clap's derive expands to env!("CARGO_PKG_VERSION"), so you fake cargo's env. # Source files are listed by hand (or you wire up --emit=dep-info .d files). build/jsontool: src/main.rs src/cli.rs src/convert.rs $(ALL_DEPS) CARGO_PKG_NAME=jsontool CARGO_PKG_VERSION=0.1.0 \ $(RUSTC) --edition=2021 --crate-type=bin --crate-name jsontool $(FLAGS) \ $(call ext,anyhow clap serde serde_json) src/main.rs # Still to write: test (rustc --test + every --extern again), doc-tests # (rustdoc --test), debug vs release flags, clean, install...``` So are you proposing GNU style makefiles for rust then? You say not another tool, just use the compiler. Either you type those commands yourself, you type them into a make style build script, or cargo or **another tool** automates them.