lean4-htt/stage0/src/lean.mk.in
Lean stage0 autoupdater bd5f8ef242 chore: update stage0
2024-08-14 09:45:24 +00:00

167 lines
4.9 KiB
Makefile
Generated

# Copyright (c) 2018 Simon Hudon. All rights reserved.
# Released under Apache 2.0 license as described in the file LICENSE.
# Authors: Simon Hudon, Sebastian Ullrich, Leonardo de Moura
# We compile all source files in $PKG/ as well as $PKG.lean. $PKG is also used for naming binary files.
ifndef PKG
PKG = $(strip $(subst .lean,, $(wildcard *.lean)))
ifneq ($(words $(PKG)), 1)
$(error no unique .lean file found in current directory, please specify PKG)
endif
endif
LEAN = lean
LEANC = leanc
LEAN_AR = @CMAKE_AR@
OUT = build
OLEAN_OUT = $(OUT)
TEMP_OUT = $(OUT)/temp
C_OUT = $(TEMP_OUT)
BC_OUT = $(TEMP_OUT)
BIN_OUT = $(OUT)/bin
LIB_OUT = $(OUT)/lib
BIN_NAME = $(PKG)
STATIC_LIB_NAME = lib$(PKG).a
LEAN_OPTS = @LEAN_EXTRA_MAKE_OPTS@
LEANC_OPTS = -O3 -DNDEBUG
LINK_OPTS =
# more FS entries to build SRCS from, for parallel build of .oleans (but not .os)
EXTRA_SRC_ROOTS =
# ignore error messages from missing parts, e.g. Leanc/
SRCS = $(shell find $(PKG) $(PKG).lean $(EXTRA_SRC_ROOTS) -name '*.lean' 2> /dev/null)
DEPS = $(addprefix $(TEMP_OUT)/,$(SRCS:.lean=.depend))
export LEAN_PATH += @LEAN_PATH_SEPARATOR@$(OLEAN_OUT)
OBJS = $(addprefix $(OLEAN_OUT)/, $(SRCS:.lean=.olean))
ifdef C_ONLY
# There are no .lean files in stage0/src/
NAT_OBJS = $(patsubst %.c,$(TEMP_OUT)/%.o,$(shell cd $(C_OUT); find $(PKG) $(PKG).c -name '*.c' 2> /dev/null))
ALL_NAT_OBJS = $(NAT_OBJS)
else
NAT_OBJS = $(patsubst %.lean,$(TEMP_OUT)/%.o,$(shell find $(PKG) $(PKG).lean -name '*.lean' 2> /dev/null))
# include `EXTRA_SRC_ROOTS` when compiling individual `.o`s but not when building libraries
ALL_NAT_OBJS = $(patsubst %.lean,$(TEMP_OUT)/%.o,$(SRCS))
endif
SHELL = /usr/bin/env bash -euo pipefail
.PHONY: all bin lib depends clean
# Disable all default make rules
.SUFFIXES:
objs: $(OBJS) $(ALL_NAT_OBJS)
bin: $(BIN_OUT)/$(BIN_NAME)
lib: $(LIB_OUT)/$(STATIC_LIB_NAME)
lib.export: $(TEMP_OUT)/$(STATIC_LIB_NAME).export
depends: $(DEPS)
$(OLEAN_OUT)/$(PKG) $(LIB_OUT) $(BIN_OUT):
@mkdir -p "$@"
# Make sure the .olean output directory exists so that `lean --deps` knows where this package's
# .olean files will be located even before any of them are actually built.
$(TEMP_OUT)/%.depend: %.lean | $(OLEAN_OUT)/$(PKG)
@mkdir -p "$(TEMP_OUT)/$(*D)"
# convert path separators and newlines on Windows
deps=`$(LEAN) --deps $<` || (echo "$(LEAN) --deps $< failed ($$?): $$deps"; exit 1); \
deps=`echo "$$deps" | tr '\\\\' / | tr -d '\\r'`; \
echo $(OLEAN_OUT)/$*.olean: $$deps > $@
$(OLEAN_OUT)/%.olean: %.lean $(TEMP_OUT)/%.depend $(MORE_DEPS)
ifdef CMAKE_LIKE_OUTPUT
@echo "[ ] Building $<"
endif
@mkdir -p $(OLEAN_OUT)/$(*D)
LEAN_OPTS="$(LEAN_OPTS)"; \
[[ -z "$(LLVM)" ]] || LEAN_OPTS+=" --bc=$(TEMP_OUT)/$*.bc.tmp"; \
$(LEAN) $$LEAN_OPTS -o "$@" -i "$(OLEAN_OUT)/$*.ilean" --c="$(TEMP_OUT)/$*.c.tmp" "$<"
# create the .c file atomically
@mv "$(TEMP_OUT)/$*.c.tmp" "$(C_OUT)/$*.c"
ifdef LLVM
@mv "$(TEMP_OUT)/$*.bc.tmp" "$(BC_OUT)/$*.bc"
endif
$(OLEAN_OUT)/%.ilean: $(OLEAN_OUT)/%.olean
@
ifndef C_ONLY
$(C_OUT)/%.c: $(OLEAN_OUT)/%.olean
@
$(BC_OUT)/%.bc: $(OLEAN_OUT)/%.olean
@
endif
ifdef LLVM
$(TEMP_OUT)/%.o.export: $(BC_OUT)/%.bc
else
$(TEMP_OUT)/%.o.export: $(C_OUT)/%.c
endif
ifdef CMAKE_LIKE_OUTPUT
@echo "[ ] Building $<"
endif
@mkdir -p "$(@D)"
$(LEANC) -c -o $@ $< $(LEANC_OPTS) -DLEAN_EXPORTING
# On Windows, rebuild .o not intended for shared libraries
# without dllexport because of symbol limit;
# on other platforms, no point in bothering
ifeq (@CMAKE_SYSTEM_NAME@, Windows)
ifdef LLVM
$(TEMP_OUT)/%.o: $(BC_OUT)/%.bc
else
$(TEMP_OUT)/%.o: $(C_OUT)/%.c
endif
ifdef CMAKE_LIKE_OUTPUT
@echo "[ ] Building $<"
endif
@mkdir -p "$(@D)"
$(LEANC) -c -o $@ $< $(LEANC_OPTS)
else
$(TEMP_OUT)/%.o: $(TEMP_OUT)/%.o.export
ln -f $< $@
endif
$(BIN_OUT)/$(BIN_NAME): $(TEMP_OUT)/$(STATIC_LIB_NAME).export | $(BIN_OUT)
ifdef CMAKE_LIKE_OUTPUT
@echo "[ ] Linking $@"
endif
# on Windows, must remove binary before writing a new one (since the old one may be in use)
@rm -f $@
$(LEANC) -o "$@" $< $(LEANC_OPTS) $(LINK_OPTS)
ifeq (@CMAKE_SYSTEM_NAME@, Windows)
$(LIB_OUT)/$(STATIC_LIB_NAME): $(NAT_OBJS) | $(LIB_OUT)
@rm -f $@
$(file >$@.in) $(foreach O,$^,$(file >>$@.in,"$O"))
@$(LEAN_AR) rcs $@ @$@.in
@rm -f $@.in
$(TEMP_OUT)/$(STATIC_LIB_NAME).export: $(addsuffix .export,$(NAT_OBJS)) | $(LIB_OUT)
@rm -f $@
$(file >$@.in) $(foreach O,$^,$(file >>$@.in,"$O"))
# "T"hin archive seems necessary to preserve paths so that we can distinguish
# between object files with the same file name when manipulating the archive for
# `libleanshared_1`
@$(LEAN_AR) rcsT $@ @$@.in
@rm -f $@.in
else
$(LIB_OUT)/$(STATIC_LIB_NAME): $(NAT_OBJS) | $(LIB_OUT)
@rm -f $@
# no response file support on macOS, but also no need for them
@$(LEAN_AR) rcs $@ $^
$(TEMP_OUT)/$(STATIC_LIB_NAME).export: $(LIB_OUT)/$(STATIC_LIB_NAME)
ln -f $< $@
endif
clean:
rm -rf $(OUT)
.PRECIOUS: $(BC_OUT)/%.bc $(C_OUT)/%.c $(TEMP_OUT)/%.o $(TEMP_OUT)/%.o.export
ifndef C_ONLY
include $(DEPS)
endif