Skip to content

Instantly share code, notes, and snippets.

@agarwal
Last active August 29, 2015 14:20
Show Gist options
  • Save agarwal/2427872a626ec2589adb to your computer and use it in GitHub Desktop.
Save agarwal/2427872a626ec2589adb to your computer and use it in GitHub Desktop.
OMake based build system for Ocsigen apps.
# OMake based build system for an Ocsigen project. I don't claim this
# to be a good solution, but it is reasonably clear and complete. I
# hope you can benefit from it.
#
# It is assumed that all files are in a lib/ sub-directory. You can
# have a mix of ml and eliom files, and they can optionally have
# corresponding mli or eliomi files. About the only thing you should
# have to do is list your project's files in SERVER_LIB_FILES and
# CLIENT_LIB_FILES.
#
# A real OMake programmer would define functions that capture all of
# the logic below, and distribute that as a project that others could
# easily use. I doubt the following is good enough, and you'll
# probably have to make more modifications for this file to really
# work for you.
open build/Common
.PHONY: lib-server lib-client \
clean clean-doc distclean
clean:
rm -rf _build
clean-doc:
rm -rf _build/doc
distclean: clean
rm -rf OMakeroot.omc .omakedb .omakedb.lock
################################################################################
# General Project Information
PROJECT = myproj
VERSION = '"dev"'
if $(test -e .git)
GIT_COMMIT = 'Some "$(shell git rev-parse HEAD)"'
export
else
GIT_COMMIT = 'None'
export
SERVER_LIB_NAME = $(PROJECT)
CLIENT_LIB_NAME = $(PROJECT)
SERVER_PACKAGES = core_kernel lwt
CLIENT_PACKAGES = lwt
ML_BASES = $(removesuffix $(basename $(ls lib/*.ml)))
MLI_BASES = $(removesuffix $(basename $(ls lib/*.mli)))
ELIOM_BASES = $(removesuffix $(basename $(ls lib/*.eliom)))
ELIOMI_BASES = $(removesuffix $(basename $(ls lib/*.eliomi)))
ML_MLI_BASES = $(intersection $(ML_BASES), $(MLI_BASES))
ML_NO_MLI_BASES = $(set-diff $(ML_BASES), $(MLI_BASES))
ELIOM_ELIOMI_BASES = $(intersection $(ELIOM_BASES), $(ELIOMI_BASES))
ELIOM_NO_ELIOMI_BASES = $(set-diff $(ELIOM_BASES), $(ELIOMI_BASES))
# Don't list signature files, only implementions.
SERVER_LIB_FILES[] =
server_stuff_a.ml
server_stuff_b.eliom
both_server_and_client_stuff.eliom
CLIENT_LIB_FILES[] =
client_stuff_a.ml
client_stuff_b.eliom
both_server_and_client_stuff.eliom
SERVER_LIB_MODULES[] =
$(removesuffix $(basename $(shell eliomdep -server -type-conv -package sexplib.syntax -sort $(addprefix lib/, $(SERVER_LIB_FILES)))))
CLIENT_LIB_MODULES[] =
$(removesuffix $(basename $(shell eliomdep -client -type-conv -sort $(addprefix lib/, $(CLIENT_LIB_FILES)))))
SCSS_FILES[] =
$(removesuffix $(basename $(ls static/css/*.scss.m4)))
################################################################################
# Build Parameters
FLAGS = -w A-4-33-41-42-44-45-48 -safe-string -bin-annot -annot -short-paths -type-conv
SERVER_ELIOM_FLAGS = $(FLAGS) -thread -package $(concat \,, $(SERVER_PACKAGES))
SERVER_ELIOMC_FLAGS = $(SERVER_ELIOM_FLAGS)
SERVER_ELIOMOPT_FLAGS = $(SERVER_ELIOM_FLAGS)
SERVER_ELIOMDEP_FLAGS = -package $(concat \,, $(SERVER_PACKAGES)) -type-conv
CLIENT_ELIOMC_FLAGS = $(FLAGS) -package $(concat \,, $(CLIENT_PACKAGES))
CLIENT_ELIOMDEP_FLAGS = -package $(concat \,, $(CLIENT_PACKAGES)) -type-conv -package sexplib.syntax
################################################################################
# Sub-directories
.SUBDIRS: .
mkdir -p _build/static/css
mkdir -p _build/static/js
mkdir -p _build/static/img
vmount(-l, static/, _build/static/)
mkdir -p _build/lib/_server
mkdir -p _build/lib/_client
vmount(-l, lib/, _build/lib/)
##############################################################################
# Client and server libraries
.SUBDIRS: _build/lib
.INCLUDE: .depend: $(basename $(ls $(ROOT)/lib/*.eliom $(ROOT)/lib/*.ml $(ROOT)/lib/*.mli))
eliomdep -server $(SERVER_ELIOMDEP_FLAGS) $+ > $@
eliomdep -client $(CLIENT_ELIOMDEP_FLAGS) $+ >> $@
############################################################################
# Server - OCaml
.SUBDIRS: _server
foreach(x => ..., $(ELIOM_BASES))
$(x).type_mli: ../$(x).eliom
eliomc $(SERVER_ELIOMC_FLAGS) -infer $<
foreach(x => ..., $(ELIOM_NO_ELIOMI_BASES))
$(x).cmo: ../$(x).eliom
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmx $(x).o: ../$(x).eliom
eliomopt $(SERVER_ELIOMOPT_FLAGS) -c $<
foreach(x => ..., $(ELIOM_ELIOMI_BASES))
$(x).cmi: ../$(x).eliomi
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmo: ../$(x).eliom $(x).cmi
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmx $(x).o: ../$(x).eliom $(x).cmi
eliomopt $(SERVER_ELIOMOPT_FLAGS) -c $<
foreach(x => ..., $(ML_NO_MLI_BASES))
$(x).cmo: ../$(x).ml
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmx $(x).o: ../$(x).ml
eliomopt $(SERVER_ELIOMOPT_FLAGS) -c $<
foreach(x => ..., $(ML_MLI_BASES))
$(x).cmi: ../$(x).mli
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmo: ../$(x).ml $(x).cmi
eliomc $(SERVER_ELIOMC_FLAGS) -c $<
$(x).cmx $(x).o: ../$(x).ml $(x).cmi
eliomopt $(SERVER_ELIOMOPT_FLAGS) -c $<
$(SERVER_LIB_NAME).cma: $(addsuffix .cmo, $(SERVER_LIB_MODULES))
eliomc $(SERVER_ELIOMC_FLAGS) -a -o $@ $+
$(SERVER_LIB_NAME).cmxa $(SERVER_LIB_NAME).a: $(addsuffix .cmx, $(SERVER_LIB_MODULES))
eliomopt $(SERVER_ELIOMOPT_FLAGS) -a -o $@ $+
$(SERVER_LIB_NAME).cmxs: $(SERVER_LIB_NAME).cmxa
eliomopt $(SERVER_ELIOMOPT_FLAGS) -shared -linkall -o $@ $<
lib-server: $(SERVER_LIB_NAME).cma $(SERVER_LIB_NAME).cmxs
.DEFAULT: lib-server
############################################################################
# Client - JavaScript
.SUBDIRS: _client
foreach(x => ..., $(ELIOM_NO_ELIOMI_BASES))
$(x).cmo $(x).cmi: ../$(x).eliom ../_server/$(x).type_mli
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -type-dir ../_server/_server -c $<
foreach(x => ..., $(ELIOM_ELIOMI_BASES))
$(x).cmi: ../$(x).eliomi ../_server/$(x).type_mli
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -type-dir ../_server/_server -c $<
$(x).cmo: ../$(x).eliom ../_server/$(x).type_mli $(x).cmi
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -type-dir ../_server/_server -c $<
foreach(x => ..., $(ML_NO_MLI_BASES))
$(x).cmo $(x).cmi: ../$(x).ml
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -c $<
foreach(x => ..., $(ML_MLI_BASES))
$(x).cmi: ../$(x).mli
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -c $<
$(x).cmo: ../$(x).ml $(x).cmi
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -c $<
# Target file's basename must match Ocsigen app name.
$(CLIENT_LIB_NAME).js: $(addsuffix .cmo, $(CLIENT_LIB_MODULES))
js_of_eliom $(CLIENT_ELIOMC_FLAGS) -o $@ $+
lib-client: $(CLIENT_LIB_NAME).js
.DEFAULT: lib-client
##############################################################################
# Static assets
.SUBDIRS: _build/static
$(CLIENT_LIB_NAME).js: $(ROOT)/_build/lib/_client/$(CLIENT_LIB_NAME).js
cp -f $< $@
.DEFAULT: $(CLIENT_LIB_NAME).js
# If you use scss, compile to css.
.SUBDIRS: css
%.scss: %.scss.m4
m4 -D FOUNDATION_LIB_PATH=$(shell opam config var foundation:lib) $< > $@
$(CLIENT_LIB_NAME).css: $(SCSS_FILES)
sass -q $(CLIENT_LIB_NAME).scss > $@
.DEFAULT: $(CLIENT_LIB_NAME).css
# Include JavaScript libraries available as OPAM packages from
# https://github.com/solvuu/opam-repo-web.
.SUBDIRS: js
jquery.min.js:
ln -s $(shell opam config var jquery:lib)/$@ .
modernizr.js:
ln -s $(shell opam config var modernizr:lib)/$@ .
d3.min.js:
ln -s $(shell opam config var d3:lib)/$@ .
foundation%.js:
ln -s $(shell opam config var foundation:lib)/js/foundation/$@ .
.DEFAULT: jquery.min.js modernizr.js foundation.js foundation.alert.js d3.min.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment