packages feed

ihp-ide-1.4.0: data/lib/IHP/Makefile.dist

.PHONY: help all

# Use bash as we sometimes use bash specific syntax, like pipefail below
#SHELL=/bin/bash
#.SHELLFLAGS := -eu -o pipefail -c

MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

GHC_EXTENSIONS=
GHC_EXTENSIONS+= -XGHC2021
GHC_EXTENSIONS+= -XOverloadedStrings
GHC_EXTENSIONS+= -XNoImplicitPrelude
GHC_EXTENSIONS+= -XImplicitParams
GHC_EXTENSIONS+= -XRank2Types
GHC_EXTENSIONS+= -XDisambiguateRecordFields
GHC_EXTENSIONS+= -XNamedFieldPuns
GHC_EXTENSIONS+= -XDuplicateRecordFields
GHC_EXTENSIONS+= -XOverloadedLabels
GHC_EXTENSIONS+= -XFlexibleContexts
GHC_EXTENSIONS+= -XTypeSynonymInstances
GHC_EXTENSIONS+= -XFlexibleInstances
GHC_EXTENSIONS+= -XQuasiQuotes
GHC_EXTENSIONS+= -XTypeFamilies
GHC_EXTENSIONS+= -XPackageImports
GHC_EXTENSIONS+= -XScopedTypeVariables
GHC_EXTENSIONS+= -XRecordWildCards
GHC_EXTENSIONS+= -XTypeApplications
GHC_EXTENSIONS+= -XDataKinds
GHC_EXTENSIONS+= -XInstanceSigs
GHC_EXTENSIONS+= -XDeriveGeneric
GHC_EXTENSIONS+= -XMultiParamTypeClasses
GHC_EXTENSIONS+= -XTypeOperators
GHC_EXTENSIONS+= -XDeriveDataTypeable
GHC_EXTENSIONS+= -XMultiWayIf
GHC_EXTENSIONS+= -XUndecidableInstances
GHC_EXTENSIONS+= -XBlockArguments
GHC_EXTENSIONS+= -XPartialTypeSignatures
GHC_EXTENSIONS+= -XLambdaCase
GHC_EXTENSIONS+= -Wno-unsafe
GHC_EXTENSIONS+= -Wno-name-shadowing
GHC_EXTENSIONS+= -Wno-monomorphism-restriction
GHC_EXTENSIONS+= -Wno-safe
GHC_EXTENSIONS+= -Wno-missing-local-signatures
GHC_EXTENSIONS+= -Wno-missing-home-modules
GHC_EXTENSIONS+= -XDefaultSignatures
GHC_EXTENSIONS+= -XEmptyDataDeriving
GHC_EXTENSIONS+= -XBangPatterns
GHC_EXTENSIONS+= -XBlockArguments
GHC_EXTENSIONS+= -XMultiWayIf
GHC_EXTENSIONS+= -XFunctionalDependencies
GHC_EXTENSIONS+= -fbyte-code
GHC_EXTENSIONS+= -Wno-partial-type-signatures
GHC_EXTENSIONS+= -XPartialTypeSignatures
GHC_EXTENSIONS+= -XStandaloneDeriving
GHC_EXTENSIONS+= -XDerivingVia
GHC_EXTENSIONS+= -Werror=missing-fields
GHC_EXTENSIONS+= -fwarn-incomplete-patterns
GHC_EXTENSIONS+= -XTemplateHaskell
GHC_EXTENSIONS+= -XDeepSubsumption
GHC_EXTENSIONS+= -XOverloadedRecordDot

GHC_RTS_FLAGS := -A256m -n2m -N

GHC_OPTIONS=-threaded -i. -ibuild -iConfig -iIHP -iIHP/IDE
GHC_OPTIONS+= ${GHC_EXTENSIONS}
GHC_OPTIONS+= -j
GHC_OPTIONS+= -package-env - # https://github.com/digitallyinduced/ihp/issues/130

ifneq ($(GHC_RTS_FLAGS),)
GHC_OPTIONS+= +RTS ${GHC_RTS_FLAGS} --RTS
endif

GHC_OPTIONS+= -package ihp
GHC_OPTIONS+= -rtsopts=all

PROD_GHC_OPTIONS+= -funbox-strict-fields
PROD_GHC_OPTIONS+= -fconstraint-solver-iterations=100
PROD_GHC_OPTIONS+= -fdicts-strict
PROD_GHC_OPTIONS+= -with-rtsopts="${APP_RTS_FLAGS}"

OPTIMIZATION_LEVEL ?= 2

.DEFAULT_GOAL := help
RUNGHC=runghc

all: build/Generated/Types.hs

.envrc:
	echo "This command is deprecated. Please use 'devenv up' instead"

build/bin:
	mkdir -p build/bin

run-production: build/bin/RunProdServer build/Generated/Types.hs ## Run Production Server
	build/bin/RunProdServer

postgres: ## Starts the postgresql server
	@if [ -s build/db/state/postmaster.pid ]; then echo "Postgres is already running."; else echo "Starting postgres"; postgres -D build/db/state -k $$PWD/build/db -c "listen_addresses="; fi

psql: ## Connects to the running postgresql server
	@psql -h $$PWD/build/db -d app

db: Application/Schema.sql Application/Fixtures.sql ## Creates a new database with the current Schema and imports Fixtures.sql
	(echo "drop schema public cascade; create schema public;" | psql -h $${PWD}/build/db -d app) && \
	psql -v ON_ERROR_STOP=1 -h $${PWD}/build/db -d app < "$${IHP_LIB}/IHPSchema.sql" && \
	psql -v ON_ERROR_STOP=1 -h $${PWD}/build/db -d app < Application/Schema.sql && \
	psql -v ON_ERROR_STOP=1 -h $${PWD}/build/db -d app < Application/Fixtures.sql

dumpdb: dump_db ## Saves the current database state into the Fixtures.sql
dump_db: ## Saves the current database state into the Fixtures.sql
	pg_dump -a --inserts --column-inserts --disable-triggers -h $$PWD/build/db app | sed -e '/^--/d' > Application/Fixtures.sql

sql_dump:  ## Saves the current database state, so it can dumped into an SQL file `make sql_dump > dump.sql`
	@pg_dump --no-owner --no-acl -h $$PWD/build/db app | sed -e '/^--/d'

build/Generated/Types.hs: Application/Schema.sql ## Rebuilds generated types
	mkdir -p build/Generated
	build-generated-code

build/bin/RunUnoptimizedProdServer: Main.hs build/bin static/prod.js static/prod.css build/Generated/Types.hs ## Quickly does a production build (all compiler optimizations disabled)
	mkdir -p build/RunUnoptimizedProdServer
	ghc -O0 ${GHC_OPTIONS} $< -o $@ -odir build/RunUnoptimizedProdServer -hidir build/RunUnoptimizedProdServer
	chmod +x $<
	rm -f build/bin/RunProdServer
	ln -s `basename $@` build/bin/RunProdServer

build/bin/RunOptimizedProdServer: Main.hs build/bin static/prod.js static/prod.css build/Generated/Types.hs ## Full production build with all ghc optimizations (takes a while)
	mkdir -p build/RunOptimizedProdServer
	ghc -O${OPTIMIZATION_LEVEL} ${GHC_OPTIONS} ${PROD_GHC_OPTIONS} $< -o $@ -odir build/RunOptimizedProdServer -hidir build/RunOptimizedProdServer
	chmod +x $<
	rm -f build/bin/RunProdServer
	ln -s `basename $@` build/bin/RunProdServer

clean: ## Resets all build and temporary files
	rm -rf build/bin
	rm -rf IHP/IHP/static/node_modules
	rm -rf build/db

static/prod.js: $(JS_FILES) ## Builds the production js bundle
	awk -v RS='\0' '{print "(function (window, document, undefined) {"; print; print "\n})(window, document);";}' $(JS_FILES) > $@

static/prod.css: $(CSS_FILES) ## Builds the production css bundle
	cat $(CSS_FILES) > $@

print-ghc-options: ## Prints all used ghc options. Useful for scripting
	@echo ${GHC_OPTIONS}

print-ghc-extensions: ## Prints all used ghc extensions. Useful for scripting
	@echo ${GHC_EXTENSIONS}

help: ## This help page
	@grep -h -E '^[a-zA-Z_///-\.]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

build/bin/Script/%: build/Script/Main/%.hs
	mkdir -p build/bin/Script
	# If RunOptimizedProdServer is compiled, likely we have object files with O2 in the build directory, so we're making an optimized script
	# Otherwise we're doing a unoptimized compile as it's much faster
	if [[ -f "build/bin/RunOptimizedProdServer" ]]; then \
		ghc -O${OPTIMIZATION_LEVEL} ${GHC_OPTIONS} ${PROD_GHC_OPTIONS} $< -o $@ -odir build/RunOptimizedProdServer -hidir build/RunOptimizedProdServer; \
	else \
		ghc -O0 ${GHC_OPTIONS} $< -o $@ -odir build/RunUnoptimizedProdServer -hidir build/RunUnoptimizedProdServer; \
	fi

build/Script/Main/%.hs: Application/Script/%.hs
	mkdir -p build/Script/Main
	echo "module Main (main) where" > $@
	echo "import IHP.ScriptSupport" >> $@
	echo "import qualified Config" >> $@
	echo "import Application.Script.$* (run)" >> $@
	echo "main = runScript Config.config run" >> $@

build/bin/RunJobs: build/RunJobs.hs ## Builds an unoptimized binary for running the job workers
	mkdir -p build/bin
	ghc -O0 -main-is 'RunJobs.main' ${GHC_OPTIONS} $< -o $@ -odir build/RunUnoptimizedProdServer -hidir build/RunUnoptimizedProdServer # We use object files by build/bin/RunUnoptimizedProdServer here to speed up compilation during deployments

build/bin/RunJobsOptimized: build/RunJobs.hs ## Builds an optimized binary for running the job workers, symlinks it to build/bin/RunJobs
	mkdir -p build/bin
	ghc -O${OPTIMIZATION_LEVEL} -main-is 'RunJobs.main' ${GHC_OPTIONS} ${PROD_GHC_OPTIONS} $< -o $@ -odir build/RunOptimizedProdServer -hidir build/RunOptimizedProdServer # We use object files by build/bin/RunOptimizedProdServer here to speed up compilation during deployments
	rm -f build/bin/RunJobs
	ln -s `basename $@` build/bin/RunJobs

build/RunJobs.hs: build/Generated/Types.hs
	echo "module RunJobs (main) where" > $@
	echo "import Application.Script.Prelude" >> $@
	echo "import IHP.ScriptSupport" >> $@
	echo "import IHP.Job.Runner" >> $@
	echo "import qualified Config" >> $@
	echo "import Main ()" >> $@
	echo "main :: IO ()" >> $@
	echo "main = runScript Config.config (runJobWorkers (workers RootApplication))" >> $@

# https://github.com/digitallyinduced/ihp/issues/130
ghci:
	ghci -package-env -

# https://github.com/digitallyinduced/ihp/issues/776
console: ghci ## Start IHP console, alias for 'make ghci'

prepare-optimized-nix-build: ## Sets the 'enabled = true' flags in default.nix, so that a 'nix-build' makes optimized binaries
	sed -i '' 's/haskellDeps/optimized = true;\n        haskellDeps/g' default.nix