Files
Leadaxe c35ccd0ea7 fix(build): restore with_clash_api on desktop/CLI — drop is AAR-only
SPEC 014 dropped with_clash_api because LxBox (Android) drives the core
over the native libbox CommandClient, making the Clash REST server dead
weight in the AAR. But the drop landed in the shared Makefile.lx LX_TAGS,
which also feeds every desktop/CLI release build (mac/windows/linux-musl
via `make -s lx-print-tags`). A CLI binary has no CommandClient channel —
it is managed by external dashboards (yacd/MetaCubeXD) over the Clash REST
API — so every desktop release since rc.1 shipped with no way to manage
the core; a config with experimental.clash_api failed fast. CI stayed
green (lx-ci BASE_TAGS kept the tag), so it was invisible in CI.

Restore with_clash_api to the desktop LX_TAGS; leave build_libbox (AAR)
unchanged. The two tag sets now diverge by design: desktop = with Clash
API, AAR = without.

Verified: desktop binary builds with with_clash_api in Tags; `check`
accepts an experimental.clash_api config; the Clash REST server comes up
live (endpoints answer 401 security-middleware, not the stub's fail-fast).

Docs: Makefile.lx comment, SPEC 014 (§2/§3.1 scoped to AAR + new §3.4),
lx-release.yml tag comment + notes line, changelog rc.17.
2026-06-30 13:23:53 +03:00

71 lines
4.3 KiB
Makefile

# Makefile.lx — sing-box-lx downstream build helpers.
# New file (zero edits to upstream Makefile) — see SPECS/CONSTITUTION.md §3.2.
# Usage: make -f Makefile.lx lx-build
# Canonical lx build-tag set for the desktop/CLI binaries — single source of truth
# (mirror changes in SPECS/004). = upstream feature set (release/DEFAULT_BUILD_TAGS)
# minus tags irrelevant to a VPN client — with_tailscale (no tailscale endpoints),
# with_ccm/with_ocm (Claude Code / OpenAI Codex proxy services), with_acme (server-side
# TLS cert issuance) — plus with_purego (CGO-free cross-compile covers
# with_naive_outbound via cronet prebuilts) and our downstream features.
#
# with_clash_api IS kept here: the desktop/CLI binary is driven through the Clash REST
# API by external dashboards (yacd / MetaCubeXD / clash-dashboard); there is no native
# CommandClient channel outside the gomobile/libbox binding, so dropping it would leave
# a CLI user with no way to manage the core (a config using experimental.clash_api would
# fail fast). It is dropped ONLY from the Android AAR (cmd/internal/build_libbox/main.go),
# where LxBox manages the core over the native libbox CommandClient and the Clash server
# is dead weight. So the two tag sets diverge by design — do NOT blindly mirror the AAR
# set here.
#
# with_purego/badlinkname need -checklinkname=0 in LX_LDFLAGS, otherwise the linker
# rejects badtls' go:linkname into crypto/tls.
LX_TAGS ?= with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_clash_api,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0,with_xhttp,with_awg,with_lx_command
# lx build counter over a given upstream base (override in CI/release: make -f Makefile.lx lx-build LX_BUILD=3).
LX_BUILD ?= 1
# Upstream base version from the nearest stable tag, excluding our own -lx tags (e.g. 1.13.13).
UPSTREAM_VERSION := $(shell git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*lx*' 2>/dev/null | sed 's/^v//')
LX_VERSION ?= $(UPSTREAM_VERSION)-lx.$(LX_BUILD)
# Stamp the version via ldflags only — constant/version.go stays untouched (zero upstream diff).
# -checklinkname=0: required by badlinkname/tfogo_checklinkname0 (Go 1.24 blocks the
# crypto/tls go:linkname in common/badtls otherwise) — mirrors upstream build_libbox.
LX_LDFLAGS = -X 'github.com/sagernet/sing-box/constant.Version=$(LX_VERSION)' -checklinkname=0 -s -w -buildid=
LX_OUTPUT ?= sing-box
# Pinned proto toolchain (SPEC 014 §3.5). Upstream `make proto` installs the codegen
# plugins at @latest, so .pb.go cannot be reproduced byte-for-byte across a rebase. We
# pin both plugins to versions matching go.mod (protobuf v1.36.11) and a gRPC codegen
# release compatible with the generated SupportPackageIsVersion9. `protoc` itself is an
# external dependency (install via your package manager, e.g. `brew install protobuf`);
# the generator at cmd/internal/protogen drives it and strips its version banner, so the
# protoc build number does not leak into the output. gofumpt normalises imports to match
# the committed style. Regenerate, never hand-edit, the .pb.go / _grpc.pb.go files.
LX_PROTOC_GEN_GO_VERSION ?= v1.36.11
LX_PROTOC_GEN_GO_GRPC_VERSION ?= v1.5.1
.PHONY: lx-build lx-version lx-print-tags lx-check lx-proto-install lx-proto
lx-proto-install: ## Install the pinned protoc-gen-go / protoc-gen-go-grpc plugins.
go install google.golang.org/protobuf/cmd/protoc-gen-go@$(LX_PROTOC_GEN_GO_VERSION)
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$(LX_PROTOC_GEN_GO_GRPC_VERSION)
go install mvdan.cc/gofumpt@latest
lx-proto: lx-proto-install ## Regenerate *.pb.go reproducibly from the merged .proto (needs system protoc on PATH).
@command -v protoc >/dev/null 2>&1 || { echo "protoc not found on PATH — install it (e.g. brew install protobuf)"; exit 1; }
go run ./cmd/internal/protogen
gofumpt -w .
lx-build: ## Build the drop-in `sing-box` binary with lx features.
CGO_ENABLED=0 go build -v -trimpath -tags "$(LX_TAGS)" -ldflags "$(LX_LDFLAGS)" -o "$(LX_OUTPUT)" ./cmd/sing-box
lx-version: ## Print the computed lx version string (e.g. 1.13.13-lx.1).
@echo "$(LX_VERSION)"
lx-print-tags: ## Print the canonical LX_TAGS set (so CI/release don't duplicate it).
@echo "$(LX_TAGS)"
lx-check: lx-build ## Validate sample configs with the freshly built binary.
./$(LX_OUTPUT) check -c lx-test/config/minimal.json