1. camlspotter
  2. opycaml

Commits

camlspotter  committed cbf2f14 Merge

omymakefile update

  • Participants
  • Parent commits dd51ce8, c9a6d92
  • Branches default

Comments (0)

Files changed (3)

File OMakefile

View file
+if $(not $(defined WithOMy))
+    include OMyMakefile
+    Installed(x)=
+    export
+
+if $(defined WithOMyApt)
+    RequireAptPackages(python-dev libncurses5-dev)
+
 OCAML_WHERE = $(shell ocamlc -where)
 
-RequireAptPackages(python-dev libncurses5-dev)
-
 ################################################################## C BUILD RULE
 
 PY_PREFIX=/usr

File OMakeroot

View file
 
 DefineCommandVars()
 
-include OMyMakefile
-
-Installed(x)=
-
 .SUBDIRS: .
 

File OMyMakefile

View file
-################################################################### directories
-
-BIG_ROOT=$(dir .)
-INSTALLED=$(BIG_ROOT)/installed
-OCAMLFIND_PREINSTALLED_LIBRARIES=
-PREFIX=$(getenv PREFIX)
+# ==========================
+# OMyMakefile
+# ==========================
+# Useful functions to build OCaml projects
 
 .PHONY: all install uninstall clean
 
-##################################################################### installed
+# Directories
+# =====================================================================
 
+#| The build root directory  
+BIG_ROOT=$(dir .)
+
+#| The prefix. Equal to the PREFIX environment variable
+PREFIX=$(getenv PREFIX)
+
+# Installation mark files
+# =======================================================================
+
+#| Installation mark files are put inside this directory.
+INSTALLED=$(BIG_ROOT)/installed
+mkdir(-p $(INSTALLED))
+
+#|Returns the installation mark files of $(packs)
 Installed(packs) = 
   return $(addprefix $(INSTALLED)/, $(packs))
 
+#|Create $(Installed $(pack)) file from the digests of $(targets)
 CreateInstalled(pack, targets)=
     println(dump md5 $(INSTALLED)/$(pack))
     chan=$(fopen $(INSTALLED)/$(pack), w)
     fprintln($(chan), $(string $(digest $(targets))))
     close($(chan))
 
-######################################################################### shell
+# Misc tools
+# ======================================================================
 
+#|ditto.
 mkdir_if_not_exists(dir) =
   if $(not $(test -e $(dir))):
     mkdir $(dir) 
+  return
 
-##################################################################### ocamlfind
+# OCamlFind
+# ========================================================================
 
+#|OMy requires OCamlFind! Do not ask me how to use OMy without OCamlFind. Please.
 USE_OCAMLFIND = true
+OCAMLFIND_DESTDIR=$(PREFIX)/lib/ocaml/site-lib
+
+#|Preinstalled libraries which are always available for normal ocaml.
+#
+# You may want to add the required packages which are built and installed out of OMy framework:
+#
+#::
+#
+#   include OMyMakefile
+#   
+#   OCAML_PREINSTALLED_PACKS += llvm # llvm has been installed already, independently
+#   
+#   Subdirs()
+#
+# It includes "findlib" by default. If you want to build findlib in OMy framework, you have to remove it from the list.
+OCAML_PREINSTALLED_PACKS[]= bigarray camlp4 dbm dynlink graphics num num-top stdlib str threads unix findlib
 
 # byte/nat
-
 NATIVE_ENABLED = $(OCAMLOPT_EXISTS)
+#|If set false in a project directory, byte compilation is disabled there.
 BYTE_ENABLED = true
 
-# compiler
-
+######################### Compiler
 OCAMLPACKAGEFLAGS=
 
 # Why we need "public." ?
-
 public.OCamlC() =
     value $(OCAMLFIND) $(OCAMLC) $(OCAMLPACKAGEFLAGS) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS)\
               $(OCAMLCFLAGS) $(OCAMLPPFLAGS) $(PREFIXED_OCAMLINCLUDES)
     value $(OCAMLFIND) $(OCAMLOPT) $(OCAMLPACKAGEFLAGS) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS)\
               $(OCAMLOPTFLAGS) $(OCAMLPPFLAGS) $(PREFIXED_OCAMLINCLUDES)
 
-# Rule to add dependency on $(files) to any ocaml generated files.
-OCamlDependsOn(files)=
-    %.cmx %.cmo %.cmi %.cma %.cmxa %.annot %.spot %.spit: $(files)
+# Spot files (OCamlSpotter)
+# ==================================================================
 
-# We first build ocamlfind before compiling any ocaml files
-OCamlDependsOn($(Installed findlib))
+#| Define OCAML_ANNOT so that custom ocamlc/ocamlopt automatically create spot/spit/annot files, even without -annot option.
+setenv(OCAML_ANNOT, 1)
 
-################################## Additional implicit rules by file extensions
+# Additional implicit rules by file extensions
 
 # annot, spot, spit files
 %.annot %.spot: %.ml %.cmi
 %.spit: %.mli 
 	$(OCamlC) -c $<
 
-# auto created .mli
+# Packages
+# =========================================================
+
+#| OCaml packages required for compilation. MyCaml* functions automatically add necessary dependencies over packages in $(OCAMLPACKS).
+# 
+# .. note:: They are also required for dependency analysis.
+public.OCAMLPACKS[]=
+
+#| CamlP4 syntax extension packages required for parsing. MyCaml* functions automatically add necessary dependencies over packages in $(CAMLP4PACKS).
+public.CAMLP4PACKS[]=
+
+# Dependencies
+# =========================================================================
+
+#|Add dependencies of any build activity over $(packages).
+#
+# .. note:: These functions introduce implicit rules: *you may need to export it, if you use this function in a local context.*
+RequirePackages(packages) =
+    required_packs = $(set-diff $(packages), $(OCAML_PREINSTALLED_PACKS))
+    .SCANNER: scan-%: $(Installed $(required_packs))
+    % : $(Installed $(required_packs))
+    export
+
+#|Add dependencies of OCaml compiled files (cmx, cmo, etc.) over $(packages).
+# $(packages) listed in OCAML_PREINSTALLED_PACKS are ignored.
+#
+# .. note:: These functions introduce implicit rules: *you may need to export it, if you use this function in a local context.*
+#
+# .. note:: Usually you do not need to call this function. Use OCAMLPACKS variable instead. 
+OCamlRequirePackages(packages) =
+    packages += findlib # Yes we use findlib
+    required_packs = $(set-diff $(packages), $(OCAML_PREINSTALLED_PACKS))
+    %.cmx %.cmo %.cmi %.cma %.cmxa %.annot %.spot %.spit : $(Installed $(required_packs))
+    export
+
+#|Add dependencies of OCaml dependency analysis and build over $(packages).
+# Use this for adding dependencies for CamlP4 extensions.
+# $(packages) listed in OCAML_PREINSTALLED_PACKS are ignored.
+#
+# .. note:: These functions introduce implicit rules: *you may need to export it, if you use this function in a local context.*
+#
+# .. note:: Usually you do not need to call this function. Use CAML4PACKS variable instead. 
+OCamlRequireCamlP4Packages(packages) =
+    packages += findlib # Yes we use findlib
+    required_packs = $(set-diff $(packages), $(OCAML_PREINSTALLED_PACKS))
+    .SCANNER: scan-ocaml-%: $(Installed $(required_packs))
+    %.cmx %.cmo %.cmi %.cma %.cmxa %.annot %.spot %.spit : $(Installed $(required_packs))
+    export
+
+#|``omake xxx.auto.mli`` generates .mli file from xxx.ml 
 %.auto.mli: %.ml
 	$(OCamlC) -i -c $< > $@
 
-################################################################# build package
+# Build rules
+# ==========================================================
 
-# library_name : target package name
-# ocamlpacks : dependent packages
-# files : ML module names
-# Todo: external C library
-# library_name : target package name
-# ocamlpacks : dependent packages
-# files : ML module names
-# Todo: external C library
+# Extend the bundled OCamlPackage with .spot creation
+public.OCamlPackage(name, files) =
+   # XXX: JYH: these variables should be marked private in 0.9.9
+   protected.OFILES   = $(addsuffix $(EXT_OBJ), $(files))
+   protected.CMOFILES = $(addsuffix .cmo, $(files))
+   protected.CMXFILES = $(addsuffix .cmx, $(files))
 
-# cmodules : C module names w/o extensions
-# linkopts : C library link options w/o OCaml flags like -cclib 
+   protected.OBJ       = $(file $(name)$(EXT_OBJ))
+   protected.CMO       = $(file $(name).cmo)
+   protected.CMX       = $(file $(name).cmx)
+   protected.CMI       = $(file $(name).cmi)
+   protected.MLI       = $(file $(name).mli)
 
+   protected.BYTE_TARGETS   = $(CMO)
+   protected.NATIVE_TARGETS = $(CMX) $(OBJ)
+
+   if $(BYTE_ENABLED)
+      BYTE_TARGETS += $(file $(name).spot)
+      export
+   else
+      NATIVE_TARGETS += $(file $(name).spot)
+      export
+
+   protected.TARGETS = $(CMI)
+   if $(NATIVE_ENABLED)
+       TARGETS += $(NATIVE_TARGETS)
+       export
+
+   if $(BYTE_ENABLED)
+       TARGETS += $(BYTE_TARGETS)
+       export
+
+   #
+   # Link commands
+   #
+   protected.BYTE_DEPS = $(CMOFILES)
+   $(BYTE_TARGETS): $(CMOFILES)
+      section rule
+         if $(or $(NATIVE_ENABLED), $(target-exists $(MLI)))
+             BYTE_DEPS += $(CMI)
+             export
+         else
+             BYTE_TARGETS += $(CMI)
+             export
+         $(BYTE_TARGETS): $(BYTE_DEPS)
+            $(OCAMLFIND) $(OCAMLC) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
+                $(OCAMLCFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMO) $(OCamlLinkSort $(CMOFILES))
+
+   protected.NATIVE_DEPS = $(CMXFILES) $(OFILES)
+   $(NATIVE_TARGETS): $(NATIVE_DEPS)
+      section rule
+         if $(target-exists $(MLI))
+            NATIVE_DEPS += $(CMI)
+            export
+         else
+            NATIVE_TARGETS += $(CMI)
+            export
+         $(NATIVE_TARGETS): $(NATIVE_DEPS)
+            $(OCAMLFIND) $(OCAMLOPTLINK) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
+                $(OCAMLOPTFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMX) $(OCamlLinkSort $(CMXFILES))
+
+   $(CMI):
+      section rule
+         if $(target-exists $(MLI))
+            $(CMI): $(MLI) :scanner: scan-ocaml-$(name).mli
+                $(OCamlC) -c $<
+         elseif $(NATIVE_ENABLED)
+            $(NATIVE_TARGETS) $(CMI): $(NATIVE_DEPS)
+               $(OCAMLFIND) $(OCAMLOPTLINK) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
+                   $(OCAMLOPTFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMX) $(OCamlLinkSort $(CMXFILES))
+         else
+            $(BYTE_TARGETS) $(CMI): $(BYTE_DEPS)
+               $(OCAMLFIND) $(OCAMLC) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
+                   $(OCAMLCFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMO) $(OCamlLinkSort $(CMOFILES))
+
+   return $(TARGETS)
+
+# Add implicit dependencies over the packages declared in OCAMLPACKS and CAMLP4PACKS
+# If this function is used in a local scope, you may want to export. 
+AddLocalOCamlPackageDependencies() =
+  # We make sure the required libraries are installed
+  OCamlRequirePackages($(OCAMLPACKS)) # must be exported!
+  OCamlRequireCamlP4Packages($(OCAMLPACKS) $(CAMLP4PACKS))
+  export
+
+#| Add a rule for OCaml package $(library_name).cmo, $(library_name).cmx and etc.
+#     library_name
+#         target package name
+#     files
+#         ML module names (without .ml)
+#     cmodules
+#         C source files (without .c)
+#     linkopts
+#         C library link option (without OCaml -cclib options)    
+#
+#  Example::
+#
+#      MyOCamlPackage(foo, alpha beta, $(EMPTY), $(EMPTY))
+#
+#  Todo: external C library
 MyOCamlPackage(library_name, files, cmodules, linkopts) =
-  # We make sure the required libraries are installed
-  installed_packs_ = $(set-diff $(OCAMLPACKS), $(OCAMLFIND_PREINSTALLED_LIBRARIES))
-  installed_packs=$(addprefix $(INSTALLED)/, $(installed_packs_))
+  AddLocalOCamlPackageDependencies()
+  export # The above thing is local: need to be exported
 
   CSTUBS=$(addsuffix .o,$(cmodules))
   CMOS=$(addsuffix .cmo,$(library_name))
   CMA=$(library_name).cma
   CMXA=$(library_name).cmxa
 
-  OCamlDependsOn($(installed_packs))
+  CSTUBLIBRARIES=
+  if $(not $(equal $(cmodules), $(EMPTY)))
+      CSTUBLIBRARIES= dll$(library_name).so lib$(library_name).a 
+      export
+
   # CR jfuruse: I guess we do not need the following
   # export # export the implicit rule above
 
   .DEFAULT: $(library_name).cmo $(library_name).cmx $(library_name).cma $(library_name).cmxa
 
-  $(CMA) $(CMXA) dll$(library_name).so lib$(library_name).a $(library_name).a : $(CSTUBS) $(CMOS) $(CMXS)
+  $(CMA) $(CMXA) $(library_name).a $(CSTUBLIBRARIES) : $(CSTUBS) $(CMOS) $(CMXS)
       ocamlmklib -verbose -o $(library_name) $(CSTUBS) $(linkopts) $(CMOS) $(CMXS)
 
   ## the followings are necessary for packing
 
 ############################################################## build ocaml exec
 
-MyOCamlProgram(name, ocamlpacks, files) =
-  # We make sure the required libraries are installed
-  installed_packs_ = $(set-diff $(ocamlpacks), $(PREINSTALLED_LIBRARIES))
-  installed_packs=$(addprefix $(INSTALLED)/, $(installed_packs_))
+#| Add a rule to build a program $(name)
+#      name
+#          Name of the program
+#      files
+#          OCaml module names (without .ml)
+MyOCamlProgram(name, files) =
+  AddLocalOCamlPackageDependencies()
+  export # The above thing is local: need to be exported
 
-  %.cmo %.cmx %.cmi: $(installed_packs)
-  export # export the implicit rule above
+  .DEFAULT: $(OCamlProgram $(name), $(files))
 
-  OCAMLPACKS = $(ocamlpacks)
-  export OCAMLPACKS
-  .DEFAULT: $(OCamlProgram $(name), $(files))
+  # The following clean the files twice if MyOCamlPackge coexists,
+  # but who cases ?
+  clean:
+    rm -f $(filter-proper-targets $(ls R, .))
+
+#|  Add rules to build OCaml library $(name)
+#        name
+#            Name of the library
+#        files
+#            OCaml module name (without .ml)
+#
+#   .. note :: Probably you should use MyOCamlPackage
+MyOCamlLibrary(name, files) =
+  AddLocalOCamlPackageDependencies()
+  export # The above thing is local: need to be exported
+
+  .DEFAULT: $(OCamlLibrary $(name), $(files))
 
   # The following clean the files twice if MyOCamlPacakge coexists,
   # but who cases ?
   clean:
     rm -f $(filter-proper-targets $(ls R, .))
 
-####################################################################### subdirs
+# Subdir traversal
+# =====================================================================
 
-# traverse the subdirs except $(dirs)
+#| Recursively traverse the subdirs except $(dirs)
 Subdirs_except(dirs) =
   # println(PWD: $(shell pwd))
 
   # The rule
   .SUBDIRS: $(VISIT_SUBDIRS)
 
-# traverse all the subdirs
+#| Recursively traverse all the subdirs
 Subdirs() =
   Subdirs_except($(array))
 
-# traverse only $(dirs)
+#| Recursively traverse the given subdirs $(dirs)
 Subdirs_only(dirs) =
  .SUBDIRS: $(dirs)
 
-########################################################################### Dot
+# Dependency dot files for Graphviz
+# ======================================================================
 
+#| Add a rule for ``depend.dot`` for a dependency graph of OCaml files in the current directory
 Dot() =
 	depend.dot: $(ls *.ml *.mli)
 	    $(OCAMLFIND) ocamldoc -I +threads $(OCAMLPACKAGEFLAGS) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLPPFLAGS) $(PREFIXED_OCAMLINCLUDES) -dot -dot-include-all -dot-reduce $+ -o $@
 
-#### C libs
 
-# name : create $(name).cma and $(name).cmxa
-# mlmodules : OCaml module names w/o extensions
-# cmodules : C module names w/o extensions
-# linkopts : C library link options w/o OCaml flags like -cclib 
-
-MyOCamlPackedLibrary(name, mlmodules, cmodules, linkopts) =
-    OCAMLPACKAGEFLAGS += -for-pack $(capitalize $(name))
-    export OCAMLPACKAGEFLAGS
-    OCamlPackage($(name), $(mlmodules))
-    CSTUBS=$(addsuffix .o,$(cmodules))
-    CMOS=$(addsuffix .cmo,$(name))
-    CMXS=$(addsuffix .cmx,$(name))
-    CMA=$(name).cma
-    CMXA=$(name).cmxa
-    $(CMA) $(CMXA) dll$(name).so lib$(name).a $(name).a : $(CSTUBS) $(CMOS) $(CMXS)
-        ocamlmklib -verbose -o $(name) $(CSTUBS) $(linkopts) $(CMOS) $(CMXS)