3 ms·
I resisted learning Make because of the clunkiness around it (Tab-indentation? C-specific features? Gross!), but after using it a few times now I've come to a
by yellowapple 3y ago
I resisted learning Make because of the clunkiness around it (Tab-indentation? C-specific features? Gross!), but after using it a few times now I've come to appreciate it.
Most recent case was for Starbound mods. The macOS and Linux versions of Starbound don't ship with any built-in tools for uploading mods to the Steam Workshop (unlike Windows, which apparently has a dedicated GUI for it), and I didn't want to have to manually go through a bunch of SteamCMD steps every time I wanted to publish an update, so for my first real mod I put together a Makefile to automatically pack all the files together (using Starbound's included asset_packer CLI tool), populate a metadata.vdf for the Steam Workshop, and run the right steamcmd incantations to get everything up. Once that was reliably working, I condensed everything into a GitHub template repo (https://github.com/YellowApple/Starbound-Mod https://github.com/YellowApple/Starbound-Mod) and ended up with a pretty straightforward (albeit a bit clunky in spots) universal Makefile:
MODNAME = StarboundMod
ifeq "$(shell uname)" "Linux"
PLATFORM = linux
endif
ifeq "$(shell uname)" "Darwin"
PLATFORM = macos
endif
SB_PACKER = ../../$(PLATFORM)/asset_packer
OUT = ./out
SRC_DIRS = achievements ai animations behaviors biomes \
celestial cinematics codex collections \
cursors damage dialog dungeons effects \
humanoid interface items leveling liquids \
monsters music names npcs objects parallax \
particles plants player projectiles quests \
radiomessages recipes rendering scripts sfx \
ships sky spawntypes species stagehands stats \
tech tenants terrain tiles tilesets treasure \
vehicles versioning weather
SRC_EXTS = config macros patch png wav
STEAMCMD = steamcmd +login $(STEAMCMD_USER)
STEAM_ID_PARSER = awk '/"publishedfileid"/{print $$2}' \
metadata.vdf | sed 's/"//g'
$(OUT)/pkg/contents.pak: $(SRC_DIRS) $(SRC_EXTS)
rm -rf $(OUT)/pkg
mkdir -p $(OUT)/pkg
$(SB_PACKER) $(OUT)/src $(OUT)/pkg/$(MODNAME).pak
$(OUT)/src:
rm -rf $(OUT)/src
mkdir -p $(OUT)/src
cp _metadata $(OUT)/src/
$(SRC_DIRS): FORCE $(OUT)/src
@cp -rv $@ $(OUT)/src/$@ 2>/dev/null \
|| echo 'No $@ folder present in mod root; skipping'
$(SRC_EXTS): FORCE $(OUT)/src
@cp -v *.$@ $(OUT)/src/ 2>/dev/null \
|| echo 'No *.$@ files present in mod root; skipping'
upload: $(OUT)/pkg/contents.pak
mkdir -p $(OUT)/workshop
cp $(OUT)/pkg/$(MODNAME).pak $(OUT)/workshop/contents.pak
cp preview.jpg $(OUT)/preview.jpg
sed 's,{{PWD}},$(PWD),g' <metadata.vdf.template >metadata.vdf
$(STEAMCMD) +workshop_build_item $(PWD)/metadata.vdf +quit
$(eval STEAM_ID=$(shell $(STEAM_ID_PARSER)))
sed -i 's/"publishedfileid" "0"/"publishedfileid" "$(STEAM_ID)"/g' \
metadata.vdf.template
clean: FORCE
rm -rf $(OUT)
rm -f metadata.vdf
FORCE:
All in all, it works well enough. Certainly nicer than trying to do it with shell scripts IMO, and I don't have to worry quite as much about whether someone else using my mod template (including my future self) is able to install some fancier build tool / task runner given how ubiquitous (GNU) Make tends to be.