#This program is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation, either version 3 of the License, or #(at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program. If not, see . #Copyright 2021 rexy712 #Makefile to generate a single executable from rust source ifeq ($(OS),Windows_NT) WINDOWS::=1 endif MAIN_SOURCE_FILE::=src/hello.rs DEPDIR::=dep LIBDIRS::=lib LDLIBS::= LDFLAGS::= RUSTFLAGS::= DEBUG_RUSTFLAGS::= MAIN_EXECUTABLE::=tester RELEASE?=0 SAVEFLAGS?=1 RUSTC::=rustc ifeq ($(WINDOWS),1) MAIN_EXECUTABLE::=$(MAIN_EXECUTABLE).exe endif .PHONY: all #prerun targets all:: #main target all:: | flags-update $(MAIN_EXECUTABLE) #postrun targets all:: #custom clean targets clean:: ########################################################################################################### #Everything past this point is internal BS, probably best not to touch it unless you know what you're doing #set the default target as the default target, otherwise the topmost target will run .DEFAULT_GOAL::=all #system dependant bullshit ifeq ($(OS),Windows_NT) #windows' cmd commands mkdir=mkdir $(subst /,\,$(1)) > NUL 2>&1 rm=del /F $(1) > NUL 2>&1 rmdir=rd /S /Q $(1) > NUL 2>&1 move=move /Y $(subst /,\,$(1)) $(subst /,\,$(2)) > NUL 2>&1 copy=copy /Y /B $(subst /,\,$(1)) $(subst /,\,$(2)) > NUL 2>&1 else #*nix terminal commands mkdir=mkdir -p $(1) rm=rm -f $(1) rmdir=rm -rf $(1) move=mv $(1) $(2) copy=cp $(1) $(2) endif #Rust is weird and should only need one depfile for a whole project since the compiler auto imports stuff MAIN_DEP_FILE::=$(DEPDIR)/$(notdir $(addsuffix .d,$(MAIN_SOURCE_FILE))) ALL_LDFLAGS+=$(LDFLAGS) $(foreach dir,$(LIBDIRS),-L'$(dir)') $(foreach lib,$(LDLIBS),"--extern $(lib)") ifneq ($(RELEASE),1) RUSTFLAGS+=$(DEBUG_RUSTFLAGS) endif ifeq ($(RELEASE),1) RUSTFLAGS+=-O else RUSTFLAGS+=-g endif COMPILER::=$(RUSTC) #setup temp files for storing compile and link flags ifeq ($(SAVEFLAGS),1) RUSTFLAGS_TMPFILE::=.rustflags.tmp LDFLAGS_TMPFILE::=.ldflags.tmp OLD_COMPILEFLAGS::=$(file <$(RUSTFLAGS_TMPFILE)) OLD_LINKFLAGS::=$(file <$(LDFLAGS_TMPFILE)) endif #Compile all the rust 'crates' $(MAIN_EXECUTABLE): $(MAIN_SOURCE_FILE) $(MAIN_DEP_FILE) $(LDFLAGS_TMPFILE) $(COMPILER) $< $(RUSTFLAGS) -o $@ $(ALL_LDFLAGS) #create a dependency tracking file so that the project rebuilds when any dep is updated $(MAIN_DEP_FILE): $(MAIN_SOURCE_FILE) $(DEPDIR) $(RUSTFLAGS_TMPFILE) $(COMPILER) $< --emit dep-info $(RUSTFLAGS) -o $@ $(DEPDIR): $(call mkdir,"$(DEPDIR)") .PHONY: flags-update flags-update: rustflags-update ldflags-update #Check if compile flags have changed since last build .PHONY: rustflags-update rustflags-update: ifeq ($(SAVEFLAGS),1) ifneq ($(OLD_COMPILEFLAGS),$(RUSTFLAGS)) $(file >$(RUSTFLAGS_TMPFILE),$(RUSTFLAGS)) endif $(RUSTFLAGS_TMPFILE): rustflags-update endif #Check if link flags have changed since last build .PHONY: ldflags-update ldflags-update: ifeq ($(SAVEFLAGS),1) ifneq ($(ALL_LDFLAGS),$(OLD_LINKFLAGS)) $(file >$(LDFLAGS_TMPFILE),$(ALL_LDFLAGS)) endif $(LDFLAGS_TMPFILE): ldflags-update endif .PHONY: clean clean:: $(call rm,"$(MAIN_EXECUTABLE)") $(call rm,"$(MAIN_EXECUTABLE).exe") $(call rmdir,"$(DEPDIR)") ifeq ($(SAVEFLAGS),1) $(call rm,"$(RUSTFLAGS_TMPFILE)") $(call rm,"$(LDFLAGS_TMPFILE)") endif #include rules from generated depfiles -include $(wildcard $(DEPDIR)/*.d)