1 ##===- bindings/ocaml/Makefile.ocaml -----------------------*- Makefile -*-===## 2 # 3 # The LLVM Compiler Infrastructure 4 # 5 # This file is distributed under the University of Illinois Open Source 6 # License. See LICENSE.TXT for details. 7 # 8 ##===----------------------------------------------------------------------===## 9 # 10 # An OCaml library is a unique project type in the context of LLVM, so rules are 11 # here rather than in Makefile.rules. 12 # 13 # Reference materials on installing OCaml libraries: 14 # 15 # https://fedoraproject.org/wiki/Packaging/OCaml 16 # http://pkg-ocaml-maint.alioth.debian.org/ocaml_packaging_policy.txt 17 # 18 ##===----------------------------------------------------------------------===## 19 20 include $(LEVEL)/Makefile.config 21 22 # CFLAGS needs to be set before Makefile.rules is included. 23 CXX.Flags += -I"$(shell $(OCAMLC) -where)" 24 C.Flags += -I"$(shell $(OCAMLC) -where)" 25 26 ifeq ($(ENABLE_SHARED),1) 27 LINK_COMPONENTS := all 28 endif 29 30 include $(LEVEL)/Makefile.common 31 32 # Intentionally ignore PROJ_prefix here. We want the ocaml stdlib. However, the 33 # user can override this with OCAML_LIBDIR or configure --with-ocaml-libdir=. 34 PROJ_libocamldir := $(DESTDIR)$(OCAML_LIBDIR) 35 OcamlDir := $(LibDir)/ocaml 36 37 # Info from llvm-config and similar 38 ifndef IS_CLEANING_TARGET 39 ifdef UsedComponents 40 UsedLibs = $(shell $(LLVM_CONFIG) --libs --system-libs $(UsedComponents)) 41 UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents)) 42 endif 43 endif 44 45 # How do we link OCaml executables with LLVM? 46 # 1) If this is a --enable-shared build, build stub libraries. This also allows 47 # to use LLVM from toplevels. 48 # 2) If this is a --disable-shared build, embed ocamlc options for building 49 # a custom runtime and a static executable. It is not possible to use LLVM 50 # from toplevels. 51 ifneq ($(ObjectsO),) 52 ifeq ($(ENABLE_SHARED),1) 53 OCAMLSTUBS := 1 54 endif 55 endif 56 57 # Tools 58 OCAMLCFLAGS += -I $(ObjDir) -I $(OcamlDir) 59 ifndef IS_CLEANING_TARGET 60 ifneq ($(ObjectsO),) 61 OCAMLAFLAGS += $(patsubst %,-cclib %, \ 62 $(filter-out -L$(LibDir),-l$(LIBRARYNAME) \ 63 $(shell $(LLVM_CONFIG) --ldflags)) \ 64 $(UsedLibs)) 65 else 66 OCAMLAFLAGS += $(patsubst %,-cclib %, \ 67 $(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG) --ldflags)) \ 68 $(UsedLibs)) 69 endif 70 endif 71 72 # -g was introduced in 3.10.0. 73 #ifneq ($(ENABLE_OPTIMIZED),1) 74 # OCAMLDEBUGFLAG := -g 75 #endif 76 77 Compile.CMI := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o) 78 Compile.CMO := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o) 79 Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o) 80 81 ifdef OCAMLSTUBS 82 # Avoid the need for LD_LIBRARY_PATH 83 ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) 84 ifneq ($(HOST_OS),Darwin) 85 OCAMLRPATH := $(RPATH) -Wl,'$(SharedLibDir)' 86 endif 87 endif 88 endif 89 90 ifdef OCAMLSTUBS 91 Archive.CMA := $(strip $(OCAMLC) -a -dllib -l$(LIBRARYNAME) $(OCAMLDEBUGFLAG) \ 92 -o) 93 else 94 Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \ 95 -o) 96 endif 97 98 ifdef OCAMLSTUBS 99 Archive.CMXA := $(strip $(OCAMLOPT) -a $(patsubst %,-cclib %, \ 100 $(LLVMLibsOptions) -l$(LIBRARYNAME) \ 101 -L$(SharedLibDir) $(OCAMLRPATH)) \ 102 $(OCAMLDEBUGFLAG) -o) 103 else 104 Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o) 105 endif 106 107 ifdef OCAMLOPT 108 Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamlLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o) 109 else 110 Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o) 111 endif 112 113 # Source files 114 ifndef OcamlSources1 115 OcamlSources1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.ml)) 116 endif 117 118 ifndef OcamlHeaders1 119 OcamlHeaders1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.mli)) 120 endif 121 122 OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1)) 123 OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1)) 124 125 OcamlSources := $(OcamlSources2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%) 126 OcamlHeaders := $(OcamlHeaders2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%) 127 128 # Intermediate files 129 ObjectsCMI := $(OcamlSources:%.ml=%.cmi) 130 ObjectsCMO := $(OcamlSources:%.ml=%.cmo) 131 ObjectsCMX := $(OcamlSources:%.ml=%.cmx) 132 133 ifdef LIBRARYNAME 134 LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma 135 LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa 136 endif 137 138 ifdef TOOLNAME 139 ToolEXE := $(ObjDir)/$(TOOLNAME)$(EXEEXT) 140 endif 141 142 # Output files 143 # The .cmo files are the only intermediates; all others are to be installed. 144 OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi) 145 OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx) 146 OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%) 147 148 ifdef LIBRARYNAME 149 LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a 150 OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma) 151 OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa) 152 endif 153 154 ifdef OCAMLSTUBS 155 SharedLib := $(OcamlDir)/dll$(LIBRARYNAME)$(SHLIBEXT) 156 endif 157 158 ifdef TOOLNAME 159 ifdef EXAMPLE_TOOL 160 OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT) 161 else 162 OutputEXE := $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT) 163 endif 164 endif 165 166 # Installation targets 167 DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%) 168 169 ifdef LIBRARYNAME 170 DestA := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a 171 DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma 172 DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa 173 endif 174 175 ifdef OCAMLSTUBS 176 DestSharedLib := $(PROJ_libocamldir)/dll$(LIBRARYNAME)$(SHLIBEXT) 177 endif 178 179 ##===- Dependencies -------------------------------------------------------===## 180 # Copy the sources into the intermediate directory because older ocamlc doesn't 181 # support -o except when linking (outputs are placed next to inputs). 182 183 $(ObjDir)/%.mli: $(PROJ_SRC_DIR)/%.mli $(ObjDir)/.dir 184 $(Verb) $(CP) -f $< $@ 185 186 $(ObjDir)/%.ml: $(PROJ_SRC_DIR)/%.ml $(ObjDir)/.dir 187 $(Verb) $(CP) -f $< $@ 188 189 $(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi) 190 191 ifdef LIBRARYNAME 192 $(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \ 193 $(OcamlDir)/.dir $(ObjDir)/.dir 194 $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@ 195 196 -include $(ObjDir)/$(LIBRARYNAME).ocamldep 197 endif 198 199 ifdef TOOLNAME 200 $(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \ 201 $(OcamlDir)/.dir $(ObjDir)/.dir 202 $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@ 203 204 -include $(ObjDir)/$(TOOLNAME).ocamldep 205 endif 206 207 ##===- Build static library from C sources --------------------------------===## 208 209 ifdef LibraryA 210 all-local:: $(LibraryA) 211 clean-local:: clean-a 212 install-local:: install-a 213 uninstall-local:: uninstall-a 214 215 $(LibraryA): $(ObjectsO) $(OcamlDir)/.dir 216 $(Echo) "Building $(BuildMode) $(notdir $@)" 217 -$(Verb) $(RM) -f $@ 218 $(Verb) $(Archive) $@ $(ObjectsO) 219 $(Verb) $(Ranlib) $@ 220 221 clean-a:: 222 -$(Verb) $(RM) -f $(LibraryA) 223 224 install-a:: $(LibraryA) 225 $(Echo) "Installing $(BuildMode) $(DestA)" 226 $(Verb) $(MKDIR) $(PROJ_libocamldir) 227 $(Verb) $(INSTALL) $(LibraryA) $(DestA) 228 $(Verb) 229 230 uninstall-a:: 231 $(Echo) "Uninstalling $(DestA)" 232 -$(Verb) $(RM) -f $(DestA) 233 endif 234 235 236 ##===- Build stub library from C sources ----------------------------------===## 237 238 ifdef SharedLib 239 all-local:: $(SharedLib) 240 clean-local:: clean-shared 241 install-local:: install-shared 242 uninstall-local:: uninstall-shared 243 244 $(SharedLib): $(ObjectsO) $(OcamlDir)/.dir 245 $(Echo) "Building $(BuildMode) $(notdir $@)" 246 $(Verb) $(Link) $(SharedLinkOptions) $(OCAMLRPATH) $(LLVMLibsOptions) \ 247 -o $@ $(ObjectsO) 248 249 clean-shared:: 250 -$(Verb) $(RM) -f $(SharedLib) 251 252 install-shared:: $(SharedLib) 253 $(Echo) "Installing $(BuildMode) $(DestSharedLib)" 254 $(Verb) $(MKDIR) $(PROJ_libocamldir) 255 $(Verb) $(INSTALL) $(SharedLib) $(DestSharedLib) 256 $(Verb) 257 258 uninstall-shared:: 259 $(Echo) "Uninstalling $(DestSharedLib)" 260 -$(Verb) $(RM) -f $(DestSharedLib) 261 endif 262 263 264 ##===- Deposit dependent libraries adjacent to Ocaml libs -----------------===## 265 266 all-local:: build-deplibs 267 clean-local:: clean-deplibs 268 install-local:: install-deplibs 269 uninstall-local:: uninstall-deplibs 270 271 build-deplibs: $(OutputLibs) 272 273 $(OcamlDir)/%.a: $(LibDir)/%.a 274 $(Verb) ln -sf $< $@ 275 276 $(OcamlDir)/%.o: $(LibDir)/%.o 277 $(Verb) ln -sf $< $@ 278 279 clean-deplibs: 280 $(Verb) $(RM) -f $(OutputLibs) 281 282 install-deplibs: 283 $(Verb) $(MKDIR) $(PROJ_libocamldir) 284 $(Verb) for i in $(DestLibs:$(PROJ_libocamldir)/%=%); do \ 285 ln -sf "$(PROJ_libdir)/$$i" "$(PROJ_libocamldir)/$$i"; \ 286 done 287 288 uninstall-deplibs: 289 $(Verb) $(RM) -f $(DestLibs) 290 291 292 ##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===## 293 294 ifneq ($(OcamlHeaders),) 295 all-local:: build-cmis 296 clean-local:: clean-cmis 297 install-local:: install-cmis 298 uninstall-local:: uninstall-cmis 299 300 build-cmis: $(OutputsCMI) 301 302 $(OcamlDir)/%.cmi: $(ObjDir)/%.cmi $(OcamlDir)/.dir 303 $(Verb) $(CP) -f $< $@ 304 305 $(ObjDir)/%.cmi: $(ObjDir)/%.mli $(ObjDir)/.dir 306 $(Echo) "Compiling $(notdir $<) for $(BuildMode) build" 307 $(Verb) $(Compile.CMI) $@ $< 308 309 clean-cmis:: 310 -$(Verb) $(RM) -f $(OutputsCMI) 311 312 # Also install the .mli's (headers) as documentation. 313 install-cmis: $(OutputsCMI) $(OcamlHeaders) 314 $(Verb) $(MKDIR) $(PROJ_libocamldir) 315 $(Verb) for i in $(OcamlHeaders:$(ObjDir)/%=%); do \ 316 $(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \ 317 $(DataInstall) $(ObjDir)/$$i "$(PROJ_libocamldir)/$$i"; \ 318 done 319 $(Verb) for i in $(OutputsCMI:$(OcamlDir)/%=%); do \ 320 $(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \ 321 $(DataInstall) $(OcamlDir)/$$i "$(PROJ_libocamldir)/$$i"; \ 322 done 323 324 uninstall-cmis:: 325 $(Verb) for i in $(OutputsCMI:$(OcamlDir)/%=%); do \ 326 $(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \ 327 $(RM) -f "$(PROJ_libocamldir)/$$i"; \ 328 done 329 $(Verb) for i in $(OcamlHeaders:$(ObjDir)/%=%); do \ 330 $(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \ 331 $(RM) -f "$(PROJ_libocamldir)/$$i"; \ 332 done 333 endif 334 335 336 ##===- Build ocaml bytecode archive (.ml's -> .cmo's -> .cma) -------------===## 337 338 $(ObjDir)/%.cmo: $(ObjDir)/%.ml 339 $(Echo) "Compiling $(notdir $<) for $(BuildMode) build" 340 $(Verb) $(Compile.CMO) $@ $< 341 342 ifdef LIBRARYNAME 343 all-local:: $(OutputCMA) 344 clean-local:: clean-cma 345 install-local:: install-cma 346 uninstall-local:: uninstall-cma 347 348 $(OutputCMA): $(LibraryCMA) $(OcamlDir)/.dir 349 $(Verb) $(CP) -f $< $@ 350 351 $(LibraryCMA): $(ObjectsCMO) $(OcamlDir)/.dir 352 $(Echo) "Archiving $(notdir $@) for $(BuildMode) build" 353 $(Verb) $(Archive.CMA) $@ $(ObjectsCMO) 354 355 clean-cma:: 356 $(Verb) $(RM) -f $(OutputCMA) $(UsedLibNames:%=$(OcamlDir)/%) 357 358 install-cma:: $(OutputCMA) 359 $(Echo) "Installing $(BuildMode) $(DestCMA)" 360 $(Verb) $(MKDIR) $(PROJ_libocamldir) 361 $(Verb) $(DataInstall) $(OutputCMA) "$(DestCMA)" 362 363 uninstall-cma:: 364 $(Echo) "Uninstalling $(DestCMA)" 365 -$(Verb) $(RM) -f $(DestCMA) 366 endif 367 368 ##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===## 369 370 # The ocamlopt compiler is supported on a set of targets disjoint from LLVM's. 371 # If unavailable, 'configure' will not define OCAMLOPT in Makefile.config. 372 ifdef OCAMLOPT 373 374 $(OcamlDir)/%.cmx: $(ObjDir)/%.cmx 375 $(Verb) $(CP) -f $< $@ 376 377 $(ObjDir)/%.cmx: $(ObjDir)/%.ml 378 $(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build" 379 $(Verb) $(Compile.CMX) $@ $< 380 381 ifdef LIBRARYNAME 382 all-local:: $(OutputCMXA) $(OutputsCMX) 383 clean-local:: clean-cmxa 384 install-local:: install-cmxa 385 uninstall-local:: uninstall-cmxa 386 387 $(OutputCMXA): $(LibraryCMXA) 388 $(Verb) $(CP) -f $< $@ 389 $(Verb) $(CP) -f $(<:.cmxa=.a) $(@:.cmxa=.a) 390 391 $(LibraryCMXA): $(ObjectsCMX) 392 $(Echo) "Archiving $(notdir $@) for $(BuildMode) build" 393 $(Verb) $(Archive.CMXA) $@ $(ObjectsCMX) 394 $(Verb) $(RM) -f $(@:.cmxa=.o) 395 396 clean-cmxa:: 397 $(Verb) $(RM) -f $(OutputCMXA) $(OutputCMXA:.cmxa=.a) $(OutputsCMX) 398 399 install-cmxa:: $(OutputCMXA) $(OutputsCMX) 400 $(Verb) $(MKDIR) $(PROJ_libocamldir) 401 $(Echo) "Installing $(BuildMode) $(DestCMXA)" 402 $(Verb) $(DataInstall) $(OutputCMXA) $(DestCMXA) 403 $(Echo) "Installing $(BuildMode) $(DestCMXA:.cmxa=.a)" 404 $(Verb) $(DataInstall) $(OutputCMXA:.cmxa=.a) $(DestCMXA:.cmxa=.a) 405 $(Verb) for i in $(OutputsCMX:$(OcamlDir)/%=%); do \ 406 $(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \ 407 $(DataInstall) $(OcamlDir)/$$i "$(PROJ_libocamldir)/$$i"; \ 408 done 409 410 uninstall-cmxa:: 411 $(Echo) "Uninstalling $(DestCMXA)" 412 $(Verb) $(RM) -f $(DestCMXA) 413 $(Echo) "Uninstalling $(DestCMXA:.cmxa=.a)" 414 $(Verb) $(RM) -f $(DestCMXA:.cmxa=.a) 415 $(Verb) for i in $(OutputsCMX:$(OcamlDir)/%=%); do \ 416 $(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \ 417 $(RM) -f $(PROJ_libocamldir)/$$i; \ 418 done 419 endif 420 endif 421 422 ##===- Build executables --------------------------------------------------===## 423 424 ifdef TOOLNAME 425 all-local:: $(OutputEXE) 426 clean-local:: clean-exe 427 428 $(OutputEXE): $(ToolEXE) $(OcamlDir)/.dir 429 $(Verb) $(CP) -f $< $@ 430 431 ifndef OCAMLOPT 432 $(ToolEXE): $(ObjectsCMO) $(OcamlDir)/.dir 433 $(Echo) "Archiving $(notdir $@) for $(BuildMode) build" 434 $(Verb) $(Archive.EXE) $@ $(ObjectsCMO) 435 else 436 $(ToolEXE): $(ObjectsCMX) $(OcamlDir)/.dir 437 $(Echo) "Archiving $(notdir $@) for $(BuildMode) build" 438 $(Verb) $(Archive.EXE) $@ $(ObjectsCMX) 439 endif 440 endif 441 442 ##===- Generate documentation ---------------------------------------------===## 443 444 $(ObjDir)/$(LIBRARYNAME).odoc: $(ObjectsCMI) 445 $(Echo) "Documenting $(notdir $@)" 446 $(Verb) $(OCAMLDOC) -I $(ObjDir) -I $(OcamlDir) -dump $@ $(OcamlHeaders) 447 448 ocamldoc: $(ObjDir)/$(LIBRARYNAME).odoc 449 450 ##===- Debugging gunk -----------------------------------------------------===## 451 printvars:: printcamlvars 452 453 printcamlvars:: 454 $(Echo) "LLVM_CONFIG : " '$(LLVM_CONFIG)' 455 $(Echo) "OCAMLCFLAGS : " '$(OCAMLCFLAGS)' 456 $(Echo) "OCAMLAFLAGS : " '$(OCAMLAFLAGS)' 457 $(Echo) "OCAMLC : " '$(OCAMLC)' 458 $(Echo) "OCAMLOPT : " '$(OCAMLOPT)' 459 $(Echo) "OCAMLDEP : " '$(OCAMLDEP)' 460 $(Echo) "Compile.CMI : " '$(Compile.CMI)' 461 $(Echo) "Compile.CMO : " '$(Compile.CMO)' 462 $(Echo) "Archive.CMA : " '$(Archive.CMA)' 463 $(Echo) "Compile.CMX : " '$(Compile.CMX)' 464 $(Echo) "Archive.CMXA : " '$(Archive.CMXA)' 465 $(Echo) "CAML_LIBDIR : " '$(CAML_LIBDIR)' 466 $(Echo) "LibraryCMA : " '$(LibraryCMA)' 467 $(Echo) "LibraryCMXA : " '$(LibraryCMXA)' 468 $(Echo) "SharedLib : " '$(SharedLib)' 469 $(Echo) "OcamlSources1: " '$(OcamlSources1)' 470 $(Echo) "OcamlSources2: " '$(OcamlSources2)' 471 $(Echo) "OcamlSources : " '$(OcamlSources)' 472 $(Echo) "OcamlHeaders1: " '$(OcamlHeaders1)' 473 $(Echo) "OcamlHeaders2: " '$(OcamlHeaders2)' 474 $(Echo) "OcamlHeaders : " '$(OcamlHeaders)' 475 $(Echo) "ObjectsCMI : " '$(ObjectsCMI)' 476 $(Echo) "ObjectsCMO : " '$(ObjectsCMO)' 477 $(Echo) "ObjectsCMX : " '$(ObjectsCMX)' 478 $(Echo) "OCAML_LIBDIR : " '$(OCAML_LIBDIR)' 479 $(Echo) "DestA : " '$(DestA)' 480 $(Echo) "DestCMA : " '$(DestCMA)' 481 $(Echo) "DestCMXA : " '$(DestCMXA)' 482 $(Echo) "DestSharedLib: " '$(DestSharedLib)' 483 $(Echo) "UsedLibs : " '$(UsedLibs)' 484 $(Echo) "UsedLibNames : " '$(UsedLibNames)' 485 486 .PHONY: printcamlvars build-cmis \ 487 clean-a clean-cmis clean-cma clean-cmxa \ 488 install-a install-cmis install-cma install-cmxa \ 489 install-exe \ 490 uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa \ 491 uninstall-exe 492