From 18366999db31cf0a5b1b48b0c63811b244f38693 Mon Sep 17 00:00:00 2001 From: Jeremy Yallop Date: Thu, 10 Apr 2014 01:02:10 +0100 Subject: [PATCH 1/8] Move foreign bindings into a separate file. --- _oasis | 3 +- lib/ffi.ml | 146 ++++++++++---------------------------------- lib/ffi_bindings.ml | 105 +++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 114 deletions(-) create mode 100644 lib/ffi_bindings.ml diff --git a/_oasis b/_oasis index 83e8894..0afd778 100644 --- a/_oasis +++ b/_oasis @@ -24,7 +24,8 @@ Library async_ssl Path: lib FindlibName: async_ssl Pack: true - Modules: Ffi, + Modules: Ffi_bindings, + Ffi, Import, Ssl, Std, diff --git a/lib/ffi.ml b/lib/ffi.ml index 78ed02f..2e46f6c 100644 --- a/lib/ffi.ml +++ b/lib/ffi.ml @@ -2,7 +2,7 @@ open Core.Std open Async.Std open Import -let foreign = Foreign.foreign +module Bindings = Ffi_bindings module Ssl_error = struct type t = @@ -27,18 +27,12 @@ let bigstring_strlen bigstr = ;; let get_error_stack = - let err_get_error = - foreign "ERR_get_error" Ctypes.(void @-> returning ulong) - in - let err_error_string_n = - foreign "ERR_error_string_n" Ctypes.(ulong @-> ptr char @-> int @-> returning void) - in let err_error_string = (* We need to write error strings from C into bigstrings. To reduce allocation, reuse scratch space for this. *) let scratch_space = Bigstring.create 1024 in fun err -> - err_error_string_n + Bindings.err_error_string_n err (Ctypes.bigarray_start Ctypes.array1 scratch_space) (Bigstring.length scratch_space); @@ -46,7 +40,7 @@ let get_error_stack = in fun () -> iter_while_rev - ~iter:err_get_error + ~iter:Bindings.err_get_error ~cond:(fun x -> x <> Unsigned.ULong.zero) |> List.rev_map ~f:err_error_string ;; @@ -55,43 +49,27 @@ let get_error_stack = (* OpenSSL_add_all_algorithms is a macro, so we have to replicate it manually. :( *) let add_all_algorithms = - let add_all_digests = - foreign "OpenSSL_add_all_digests" Ctypes.(void @-> returning void) - in - let add_all_ciphers = - foreign "OpenSSL_add_all_ciphers" Ctypes.(void @-> returning void) - in fun () -> - add_all_ciphers (); - add_all_digests (); + Bindings.add_all_ciphers (); + Bindings.add_all_digests (); ;; (* Call the openssl initialization method if it hasn't been already. *) (* val possibly_init : unit -> unit *) let possibly_init = - let init = foreign "SSL_library_init" Ctypes.(void @-> returning ulong) in - let ssl_load_error_strings = - foreign "SSL_load_error_strings" Ctypes.(void @-> returning void) - in let initialized = ref false in fun () -> if not !initialized then begin initialized := true; (* SSL_library_init() always returns "1", so it is safe to discard the return value. *) - ignore (init () : Unsigned.ulong); - ssl_load_error_strings (); + ignore (Bindings.init () : Unsigned.ulong); + Bindings.ssl_load_error_strings (); add_all_algorithms (); end ;; -let ssl_method_t = Ctypes.(void @-> returning (ptr void)) -let sslv3_method = foreign "SSLv3_method" ssl_method_t -let tlsv1_method = foreign "TLSv1_method" ssl_method_t -let sslv23_method = foreign "SSLv23_method" ssl_method_t - module Ssl_ctx = struct - type t = unit Ctypes.ptr let t = Ctypes.(ptr void) (* for use in ctypes type signatures *) @@ -99,40 +77,25 @@ module Ssl_ctx = struct let sexp_of_t x = Ctypes.(ptr_diff x null) |> <:sexp_of> let create_exn = - (* SSLv2 isn't secure, so we don't use it. If you really really really need it, use - SSLv23 which will at least try to upgrade the security whenever possible. - - let sslv2_method = foreign "SSLv2_method" ssl_method_t - *) - let ssl_ctx_new = - foreign "SSL_CTX_new" Ctypes.(ptr void @-> returning (ptr_opt void)) - in - let ssl_ctx_free = - foreign "SSL_CTX_free" Ctypes.(t @-> returning void) - in fun ver -> possibly_init (); let ver_method = let module V = Version in match ver with - | V.Sslv3 -> sslv3_method () - | V.Tlsv1 -> tlsv1_method () - | V.Sslv23 -> sslv23_method () + | V.Sslv3 -> Bindings.sslv3_method () + | V.Tlsv1 -> Bindings.tlsv1_method () + | V.Sslv23 -> Bindings.sslv23_method () in - match ssl_ctx_new ver_method with + match Bindings.Ssl_ctx.ssl_ctx_new ver_method with | None -> failwith "Could not allocate a new SSL context." | Some p -> - Gc.add_finalizer_exn p ssl_ctx_free; + Gc.add_finalizer_exn p Bindings.Ssl_ctx.ssl_ctx_free; p ;; let load_verify_locations = - let ssl_ctx_load_verify_locations = - foreign "SSL_CTX_load_verify_locations" - Ctypes.(t @-> string_opt @-> string_opt @-> returning int) - in fun ?ca_file ?ca_path ctx -> - In_thread.run (fun () -> ssl_ctx_load_verify_locations ctx ca_file ca_path) + In_thread.run (fun () -> Bindings.Ssl_ctx.ssl_ctx_load_verify_locations ctx ca_file ca_path) >>= function | 0 -> Deferred.return (Or_error.return ()) | _ -> Deferred.return begin @@ -152,33 +115,21 @@ module Bio = struct let sexp_of_t bio = Ctypes.(ptr_diff bio null) |> <:sexp_of> let create = - let bio_new = - foreign "BIO_new" Ctypes.(ptr void @-> returning t) - in - let bio_s_mem = - foreign "BIO_s_mem" Ctypes.(void @-> returning (ptr void)) - in fun () -> - bio_s_mem () - |> bio_new + Bindings.Bio.bio_s_mem () + |> Bindings.Bio.bio_new ;; let read = - let bio_read = - foreign "BIO_read" Ctypes.(t @-> ptr char @-> int @-> returning int) - in fun bio ~buf ~len -> - let retval = bio_read bio buf len in + let retval = Bindings.Bio.bio_read bio buf len in if verbose then Debug.amf _here_ "BIO_read(%i) -> %i" len retval; retval ;; let write = - let bio_write = - foreign "BIO_write" Ctypes.(t @-> string @-> int @-> returning int) - in fun bio ~buf ~len -> - let retval = bio_write bio buf len in + let retval = Bindings.Bio.bio_write bio buf len in if verbose then Debug.amf _here_ "BIO_write(%i) -> %i" len retval; retval ;; @@ -193,42 +144,34 @@ module Ssl = struct let sexp_of_t ssl = Ctypes.(ptr_diff ssl null) |> <:sexp_of> let create_exn = - let ssl_new = foreign "SSL_new" Ctypes.(Ssl_ctx.t @-> returning t) in - let ssl_free = foreign "SSL_free" Ctypes.( t @-> returning void) in fun ctx -> - let p = ssl_new ctx in + let p = Bindings.Ssl.ssl_new ctx in if p = Ctypes.null then failwith "Unable to allocate an SSL connection." else begin - Gc.add_finalizer_exn p ssl_free; + Gc.add_finalizer_exn p Bindings.Ssl.ssl_free; p end ;; let set_method = - let ssl_set_method = - foreign "SSL_set_ssl_method" Ctypes.(t @-> ptr void @-> returning int) - in fun t version -> let version_method = let open Version in match version with - | Sslv3 -> sslv3_method () - | Tlsv1 -> tlsv1_method () - | Sslv23 -> sslv23_method () + | Sslv3 -> Bindings.sslv3_method () + | Tlsv1 -> Bindings.tlsv1_method () + | Sslv23 -> Bindings.sslv23_method () in - match ssl_set_method t version_method with + match Bindings.Ssl.ssl_set_method t version_method with | 1 -> () | e -> failwithf "Failed to set SSL version: %i" e () ;; let get_error = - let ssl_get_error = - foreign "SSL_get_error" Ctypes.(ptr void @-> int @-> returning int) - in let module E = Ssl_error in fun ssl ~retval -> - ssl_get_error ssl retval + Bindings.Ssl.ssl_get_error ssl retval |> function | 1 -> Error E.Ssl_error | 2 -> Error E.Want_read @@ -242,21 +185,14 @@ module Ssl = struct ;; let set_initial_state = - let ssl_set_connect_state = - foreign "SSL_set_connect_state" Ctypes.(t @-> returning void) - in - let ssl_set_accept_state = - foreign "SSL_set_accept_state" Ctypes.(t @-> returning void) - in fun ssl -> function - | `Connect -> ssl_set_connect_state ssl - | `Accept -> ssl_set_accept_state ssl + | `Connect -> Bindings.Ssl.ssl_set_connect_state ssl + | `Accept -> Bindings.Ssl.ssl_set_accept_state ssl ;; let connect = - let ssl_connect = foreign "SSL_connect" Ctypes.(t @-> returning int) in fun ssl -> - let retval = ssl_connect ssl in + let retval = Bindings.Ssl.ssl_connect ssl in Result.(get_error ssl ~retval >>= fun _ -> if verbose then Debug.amf _here_ "SSL_connect -> %i" retval; @@ -264,38 +200,28 @@ module Ssl = struct ;; let accept = - let ssl_accept = foreign "SSL_accept" Ctypes.(t @-> returning int) in fun ssl -> - let retval = ssl_accept ssl in + let retval = Bindings.Ssl.ssl_accept ssl in Result.(get_error ssl ~retval >>= fun _ -> if verbose then Debug.amf _here_ "SSL_accept -> %i" retval; return ()) let set_bio = - let ssl_set_bio = - foreign "SSL_set_bio" Ctypes.(t @-> Bio.t @-> Bio.t @-> returning void) - in fun ssl ~input ~output -> - ssl_set_bio ssl input output + Bindings.Ssl.ssl_set_bio ssl input output ;; let read = - let ssl_read = - foreign "SSL_read" Ctypes.(t @-> ptr char @-> int @-> returning int) - in fun ssl ~buf ~len -> - let retval = ssl_read ssl buf len in + let retval = Bindings.Ssl.ssl_read ssl buf len in if verbose then Debug.amf _here_ "SSL_read(%i) -> %i" len retval; get_error ssl ~retval ;; let write = - let ssl_write = - foreign "SSL_write" Ctypes.(t @-> string @-> int @-> returning int) - in fun ssl ~buf ~len -> - let retval = ssl_write ssl buf len in + let retval = Bindings.Ssl.ssl_write ssl buf len in if verbose then Debug.amf _here_ "SSL_write(%i) -> %i" len retval; get_error ssl ~retval ;; @@ -306,26 +232,20 @@ module Ssl = struct ;; let use_certificate_file = - let ssl_use_certificate_file = - foreign "SSL_use_certificate_file" Ctypes.(t @-> string @-> int @-> returning int) - in fun ssl ~crt ~file_type -> let c_enum = type_to_c_enum file_type in In_thread.run (fun () -> - let retval = ssl_use_certificate_file ssl crt c_enum in + let retval = Bindings.Ssl.ssl_use_certificate_file ssl crt c_enum in if retval > 0 then Ok () else Error (get_error_stack ())) ;; let use_private_key_file = - let ssl_use_private_key_file = - foreign "SSL_use_PrivateKey_file" Ctypes.(t @-> string @-> int @-> returning int) - in fun ssl ~key ~file_type -> let c_enum = type_to_c_enum file_type in In_thread.run (fun () -> - let retval = ssl_use_private_key_file ssl key c_enum in + let retval = Bindings.Ssl.ssl_use_private_key_file ssl key c_enum in if retval > 0 then Ok () else Error (get_error_stack ())) diff --git a/lib/ffi_bindings.ml b/lib/ffi_bindings.ml new file mode 100644 index 0000000..9119e34 --- /dev/null +++ b/lib/ffi_bindings.ml @@ -0,0 +1,105 @@ +let foreign = Foreign.foreign + +let err_get_error = foreign "ERR_get_error" + Ctypes.(void @-> returning ulong) + +let err_error_string_n = foreign "ERR_error_string_n" + Ctypes.(ulong @-> ptr char @-> int @-> returning void) + +let add_all_digests = foreign "OpenSSL_add_all_digests" + Ctypes.(void @-> returning void) + +let add_all_ciphers = foreign "OpenSSL_add_all_ciphers" + Ctypes.(void @-> returning void) + +let init = foreign "SSL_library_init" + Ctypes.(void @-> returning ulong) + +let ssl_load_error_strings = foreign "SSL_load_error_strings" + Ctypes.(void @-> returning void) + +let ssl_method_t = Ctypes.(void @-> returning (ptr void)) +let sslv3_method = foreign "SSLv3_method" ssl_method_t +let tlsv1_method = foreign "TLSv1_method" ssl_method_t +let sslv23_method = foreign "SSLv23_method" ssl_method_t +(* SSLv2 isn't secure, so we don't use it. If you really really really need it, use + SSLv23 which will at least try to upgrade the security whenever possible. + + let sslv2_method = foreign "SSLv2_method" ssl_method_t +*) + + +module Ssl_ctx = +struct + let t = Ctypes.(ptr void) + + let ssl_ctx_new = foreign "SSL_CTX_new" + Ctypes.(ptr void @-> returning (ptr_opt void)) + + let ssl_ctx_free = foreign "SSL_CTX_free" + Ctypes.(t @-> returning void) + + let ssl_ctx_load_verify_locations = foreign "SSL_CTX_load_verify_locations" + Ctypes.(t @-> string_opt @-> string_opt @-> returning int) +end + +module Bio = +struct + let t = Ctypes.(ptr void) (* for use in ctypes signatures *) + + let bio_new = foreign "BIO_new" + Ctypes.(ptr void @-> returning t) + + let bio_s_mem = foreign "BIO_s_mem" + Ctypes.(void @-> returning (ptr void)) + + let bio_read = foreign "BIO_read" + Ctypes.(t @-> ptr char @-> int @-> returning int) + + let bio_write = foreign "BIO_write" + Ctypes.(t @-> string @-> int @-> returning int) +end + +module Ssl = +struct + let t = Ctypes.(ptr void) + + let ssl_new = foreign "SSL_new" + Ctypes.(Ssl_ctx.t @-> returning t) + + let ssl_free = foreign "SSL_free" + Ctypes.(t @-> returning void) + + let ssl_set_method = foreign "SSL_set_ssl_method" + Ctypes.(t @-> ptr void @-> returning int) + + let ssl_get_error = foreign "SSL_get_error" + Ctypes.(ptr void @-> int @-> returning int) + + let ssl_set_connect_state = foreign "SSL_set_connect_state" + Ctypes.(t @-> returning void) + + let ssl_set_accept_state = foreign "SSL_set_accept_state" + Ctypes.(t @-> returning void) + + let ssl_connect = foreign "SSL_connect" + Ctypes.(t @-> returning int) + + let ssl_accept = foreign "SSL_accept" + Ctypes.(t @-> returning int) + + let ssl_set_bio = foreign "SSL_set_bio" + Ctypes.(t @-> Bio.t @-> Bio.t @-> returning void) + + let ssl_read = foreign "SSL_read" + Ctypes.(t @-> ptr char @-> int @-> returning int) + + let ssl_write = foreign "SSL_write" + Ctypes.(t @-> string @-> int @-> returning int) + + let ssl_use_certificate_file = foreign "SSL_use_certificate_file" + Ctypes.(t @-> string @-> int @-> returning int) + + let ssl_use_private_key_file = foreign "SSL_use_PrivateKey_file" + Ctypes.(t @-> string @-> int @-> returning int) +end From 789385ae5e2532f9ee19b66a9240f63751ee075e Mon Sep 17 00:00:00 2001 From: Jeremy Yallop Date: Thu, 10 Apr 2014 01:33:41 +0100 Subject: [PATCH 2/8] Switch to using OCamlMakefile --- META | 9 + Makefile | 65 +-- OCamlMakefile | 1239 +++++++++++++++++++++++++++++++++++++++++++++++++ _oasis | 56 --- _tags | 3 - configure | 5 - setup.ml | 8 - 7 files changed, 1268 insertions(+), 117 deletions(-) create mode 100644 META create mode 100644 OCamlMakefile delete mode 100644 _oasis delete mode 100644 _tags delete mode 100755 configure delete mode 100644 setup.ml diff --git a/META b/META new file mode 100644 index 0000000..52e017c --- /dev/null +++ b/META @@ -0,0 +1,9 @@ +version = "111.08.00" +description = "Async wrappers for ssl" +requires = +"core async ctypes ctypes.foreign herelib pa_bench pa_bench.syntax pa_ounit sexplib threads" +archive(byte) = "async_ssl.cma" +archive(byte, plugin) = "async_ssl.cma" +archive(native) = "async_ssl.cmxa" +archive(native, plugin) = "async_ssl.cmxs" +exists_if = "async_ssl.cma" diff --git a/Makefile b/Makefile index 04cbd69..47b4503 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,28 @@ -# Generic Makefile for oasis project +USE_CAMLP4=yes -# Set to setup.exe for the release -SETUP := setup-dev.exe +PACKS=sexplib.syntax,sexplib,pa_ounit.syntax,pa_ounit,pa_bench.syntax,pa_bench,herelib.syntax,herelib,ctypes.foreign,ctypes,async,core -# Default rule -default: build +CLIBS=ssl crypto -# Setup for the development version -setup-dev.exe: _oasis setup.ml - grep -v '^#' setup.ml > setup_dev.ml - ocamlfind ocamlopt -o $@ -linkpkg -package ocamlbuild,oasis.dynrun setup_dev.ml || ocamlfind ocamlc -o $@ -linkpkg -package ocamlbuild,oasis.dynrun setup_dev.ml || true - rm -f setup_dev.* +OCAMLDEP = ocamldep -package $(PACKS) -syntax camlp4o +OCAMLFLAGS = -syntax camlp4o -thread +RESULT=async_ssl +LIB_PACK_NAME=Async_ssl -# Setup for the release -setup.exe: setup.ml - ocamlopt.opt -o $@ $< || ocamlopt -o $@ $< || ocamlc -o $@ $< - rm -f setup.cmx setup.cmi setup.o setup.obj setup.cmo +SOURCES=lib/import.ml \ + lib/version.ml lib/version.mli \ + lib/ffi_bindings.ml \ + lib/ffi.ml lib/ffi.mli \ + lib/ssl.ml lib/ssl.mli \ + lib/std.ml -build: $(SETUP) setup.data - ./$(SETUP) -build $(BUILDFLAGS) +LIBINSTALL_FILES = lib/ffi.mli lib/ssl.mli lib/version.mli \ + Async_ssl.cmi Async_ssl.cmo Async_ssl.cmx \ + async_ssl.cma async_ssl.cmxa async_ssl.a \ + META -doc: $(SETUP) setup.data build - ./$(SETUP) -doc $(DOCFLAGS) +all: byte-code-library native-code-library -test: $(SETUP) setup.data build - ./$(SETUP) -test $(TESTFLAGS) +install: libinstall -all: $(SETUP) - ./$(SETUP) -all $(ALLFLAGS) - -install: $(SETUP) setup.data - ./$(SETUP) -install $(INSTALLFLAGS) - -uninstall: $(SETUP) setup.data - ./$(SETUP) -uninstall $(UNINSTALLFLAGS) - -reinstall: $(SETUP) setup.data - ./$(SETUP) -reinstall $(REINSTALLFLAGS) - -clean: $(SETUP) - ./$(SETUP) -clean $(CLEANFLAGS) - -distclean: $(SETUP) - ./$(SETUP) -distclean $(DISTCLEANFLAGS) - -configure: $(SETUP) - ./$(SETUP) -configure $(CONFIGUREFLAGS) - -setup.data: $(SETUP) - ./$(SETUP) -configure $(CONFIGUREFLAGS) - -.PHONY: default build doc test all install uninstall reinstall clean distclean configure +-include OCamlMakefile diff --git a/OCamlMakefile b/OCamlMakefile new file mode 100644 index 0000000..dc545af --- /dev/null +++ b/OCamlMakefile @@ -0,0 +1,1239 @@ +########################################################################### +# OCamlMakefile +# Copyright (C) 1999-2007 Markus Mottl +# +# For updates see: +# http://www.ocaml.info/home/ocaml_sources.html +# +########################################################################### + +# Modified by damien for .glade.ml compilation + +# Set these variables to the names of the sources to be processed and +# the result variable. Order matters during linkage! + +ifndef SOURCES + SOURCES := foo.ml +endif +export SOURCES + +ifndef RES_CLIB_SUF + RES_CLIB_SUF := _stubs +endif +export RES_CLIB_SUF + +ifndef RESULT + RESULT := foo +endif +export RESULT := $(strip $(RESULT)) + +export LIB_PACK_NAME + +ifndef DOC_FILES + DOC_FILES := $(filter %.mli, $(SOURCES)) +endif +export DOC_FILES +FIRST_DOC_FILE := $(firstword $(DOC_FILES)) + +export BCSUFFIX +export NCSUFFIX + +ifndef TOPSUFFIX + TOPSUFFIX := .top +endif +export TOPSUFFIX + +# Eventually set include- and library-paths, libraries to link, +# additional compilation-, link- and ocamlyacc-flags +# Path- and library information needs not be written with "-I" and such... +# Define THREADS if you need it, otherwise leave it unset (same for +# USE_CAMLP4)! + +export THREADS +export VMTHREADS +export ANNOTATE +export USE_CAMLP4 + +export INCDIRS +export LIBDIRS +export EXTLIBDIRS +export RESULTDEPS +export OCAML_DEFAULT_DIRS + +export LIBS +export CLIBS +export CFRAMEWORKS + +export OCAMLFLAGS +export OCAMLNCFLAGS +export OCAMLBCFLAGS + +export OCAMLLDFLAGS +export OCAMLNLDFLAGS +export OCAMLBLDFLAGS + +export OCAMLMKLIB_FLAGS + +ifndef OCAMLCPFLAGS + OCAMLCPFLAGS := a +endif +export OCAMLCPFLAGS + +ifndef DOC_DIR + DOC_DIR := doc +endif +export DOC_DIR + +export PPFLAGS + +export LFLAGS +export YFLAGS +export IDLFLAGS + +export OCAMLDOCFLAGS + +export OCAMLFIND_INSTFLAGS + +export DVIPSFLAGS + +export STATIC + +# Add a list of optional trash files that should be deleted by "make clean" +export TRASH + +ECHO := echo + +ifdef REALLY_QUIET + export REALLY_QUIET + ECHO := true + LFLAGS := $(LFLAGS) -q + YFLAGS := $(YFLAGS) -q +endif + +#################### variables depending on your OCaml-installation + +ifdef MINGW + export MINGW + WIN32 := 1 + CFLAGS_WIN32 := -mno-cygwin +endif +ifdef MSVC + export MSVC + WIN32 := 1 + ifndef STATIC + CPPFLAGS_WIN32 := -DCAML_DLL + endif + CFLAGS_WIN32 += -nologo + EXT_OBJ := obj + EXT_LIB := lib + ifeq ($(CC),gcc) + # work around GNU Make default value + ifdef THREADS + CC := cl -MT + else + CC := cl + endif + endif + ifeq ($(CXX),g++) + # work around GNU Make default value + CXX := $(CC) + endif + CFLAG_O := -Fo +endif +ifdef WIN32 + EXT_CXX := cpp + EXE := .exe +endif + +ifndef EXT_OBJ + EXT_OBJ := o +endif +ifndef EXT_LIB + EXT_LIB := a +endif +ifndef EXT_CXX + EXT_CXX := cc +endif +ifndef EXE + EXE := # empty +endif +ifndef CFLAG_O + CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)! +endif + +export CC +export CXX +export CFLAGS +export CXXFLAGS +export LDFLAGS +export CPPFLAGS + +ifndef RPATH_FLAG + ifdef ELF_RPATH_FLAG + RPATH_FLAG := $(ELF_RPATH_FLAG) + else + RPATH_FLAG := -R + endif +endif +export RPATH_FLAG + +ifndef MSVC +ifndef PIC_CFLAGS + PIC_CFLAGS := -fPIC +endif +ifndef PIC_CPPFLAGS + PIC_CPPFLAGS := -DPIC +endif +endif + +export PIC_CFLAGS +export PIC_CPPFLAGS + +BCRESULT := $(addsuffix $(BCSUFFIX), $(RESULT)) +NCRESULT := $(addsuffix $(NCSUFFIX), $(RESULT)) +TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT)) + +ifndef OCAMLFIND + OCAMLFIND := ocamlfind +endif +export OCAMLFIND + +ifndef OCAMLC + OCAMLC := ocamlc +endif +export OCAMLC + +ifndef OCAMLOPT + OCAMLOPT := ocamlopt +endif +export OCAMLOPT + +ifndef OCAMLMKTOP + OCAMLMKTOP := ocamlmktop +endif +export OCAMLMKTOP + +ifndef OCAMLCP + OCAMLCP := ocamlcp +endif +export OCAMLCP + +ifndef OCAMLDEP + OCAMLDEP := ocamldep +endif +export OCAMLDEP + +ifndef OCAMLLEX + OCAMLLEX := ocamllex +endif +export OCAMLLEX + +ifndef OCAMLYACC + OCAMLYACC := ocamlyacc +endif +export OCAMLYACC + +ifndef OCAMLMKLIB + OCAMLMKLIB := ocamlmklib +endif +export OCAMLMKLIB + +ifndef OCAML_GLADECC + OCAML_GLADECC := lablgladecc2 +endif +export OCAML_GLADECC + +ifndef OCAML_GLADECC_FLAGS + OCAML_GLADECC_FLAGS := +endif +export OCAML_GLADECC_FLAGS + +ifndef CAMELEON_REPORT + CAMELEON_REPORT := report +endif +export CAMELEON_REPORT + +ifndef CAMELEON_REPORT_FLAGS + CAMELEON_REPORT_FLAGS := +endif +export CAMELEON_REPORT_FLAGS + +ifndef CAMELEON_ZOGGY + CAMELEON_ZOGGY := camlp4o pa_zog.cma pr_o.cmo +endif +export CAMELEON_ZOGGY + +ifndef CAMELEON_ZOGGY_FLAGS + CAMELEON_ZOGGY_FLAGS := +endif +export CAMELEON_ZOGGY_FLAGS + +ifndef OXRIDL + OXRIDL := oxridl +endif +export OXRIDL + +ifndef CAMLIDL + CAMLIDL := camlidl +endif +export CAMLIDL + +ifndef CAMLIDLDLL + CAMLIDLDLL := camlidldll +endif +export CAMLIDLDLL + +ifndef NOIDLHEADER + MAYBE_IDL_HEADER := -header +endif +export NOIDLHEADER + +export NO_CUSTOM + +ifndef CAMLP4 + CAMLP4 := camlp4 +endif +export CAMLP4 + +ifndef REAL_OCAMLFIND + ifdef PACKS + ifndef CREATE_LIB + ifdef THREADS + PACKS += threads + endif + endif + empty := + space := $(empty) $(empty) + comma := , + ifdef PREDS + PRE_OCAML_FIND_PREDICATES := $(subst $(space),$(comma),$(PREDS)) + PRE_OCAML_FIND_PACKAGES := $(subst $(space),$(comma),$(PACKS)) + OCAML_FIND_PREDICATES := -predicates $(PRE_OCAML_FIND_PREDICATES) + # OCAML_DEP_PREDICATES := -syntax $(PRE_OCAML_FIND_PREDICATES) + OCAML_FIND_PACKAGES := $(OCAML_FIND_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) + OCAML_DEP_PACKAGES := $(OCAML_DEP_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) + else + OCAML_FIND_PACKAGES := -package $(subst $(space),$(comma),$(PACKS)) + OCAML_DEP_PACKAGES := + endif + OCAML_FIND_LINKPKG := -linkpkg + REAL_OCAMLFIND := $(OCAMLFIND) + endif +endif + +export OCAML_FIND_PACKAGES +export OCAML_DEP_PACKAGES +export OCAML_FIND_LINKPKG +export REAL_OCAMLFIND + +ifndef OCAMLDOC + OCAMLDOC := ocamldoc +endif +export OCAMLDOC + +ifndef LATEX + LATEX := latex +endif +export LATEX + +ifndef DVIPS + DVIPS := dvips +endif +export DVIPS + +ifndef PS2PDF + PS2PDF := ps2pdf +endif +export PS2PDF + +ifndef OCAMLMAKEFILE + OCAMLMAKEFILE := OCamlMakefile +endif +export OCAMLMAKEFILE + +ifndef OCAMLLIBPATH + OCAMLLIBPATH := \ + $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/local/lib/ocaml) +endif +export OCAMLLIBPATH + +ifndef OCAML_LIB_INSTALL + OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib +endif +export OCAML_LIB_INSTALL + +########################################################################### + +#################### change following sections only if +#################### you know what you are doing! + +# delete target files when a build command fails +.PHONY: .DELETE_ON_ERROR +.DELETE_ON_ERROR: + +# for pedants using "--warn-undefined-variables" +export MAYBE_IDL +export REAL_RESULT +export CAMLIDLFLAGS +export THREAD_FLAG +export RES_CLIB +export MAKEDLL +export ANNOT_FLAG +export C_OXRIDL +export SUBPROJS +export CFLAGS_WIN32 +export CPPFLAGS_WIN32 + +INCFLAGS := + +SHELL := /bin/sh + +MLDEPDIR := ._d +BCDIDIR := ._bcdi +NCDIDIR := ._ncdi + +FILTER_EXTNS := %.mli %.ml %.mll %.mly %.idl %.oxridl %.c %.m %.$(EXT_CXX) %.rep %.zog %.glade + +FILTERED := $(filter $(FILTER_EXTNS), $(SOURCES)) +SOURCE_DIRS := $(filter-out ./, $(sort $(dir $(FILTERED)))) + +FILTERED_REP := $(filter %.rep, $(FILTERED)) +DEP_REP := $(FILTERED_REP:%.rep=$(MLDEPDIR)/%.d) +AUTO_REP := $(FILTERED_REP:.rep=.ml) + +FILTERED_ZOG := $(filter %.zog, $(FILTERED)) +DEP_ZOG := $(FILTERED_ZOG:%.zog=$(MLDEPDIR)/%.d) +AUTO_ZOG := $(FILTERED_ZOG:.zog=.ml) + +FILTERED_GLADE := $(filter %.glade, $(FILTERED)) +DEP_GLADE := $(FILTERED_GLADE:%.glade=$(MLDEPDIR)/%.d) +AUTO_GLADE := $(FILTERED_GLADE:.glade=.ml) + +FILTERED_ML := $(filter %.ml, $(FILTERED)) +DEP_ML := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d) + +FILTERED_MLI := $(filter %.mli, $(FILTERED)) +DEP_MLI := $(FILTERED_MLI:.mli=.di) + +FILTERED_MLL := $(filter %.mll, $(FILTERED)) +DEP_MLL := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d) +AUTO_MLL := $(FILTERED_MLL:.mll=.ml) + +FILTERED_MLY := $(filter %.mly, $(FILTERED)) +DEP_MLY := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di) +AUTO_MLY := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml) + +FILTERED_IDL := $(filter %.idl, $(FILTERED)) +DEP_IDL := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di) +C_IDL := $(FILTERED_IDL:%.idl=%_stubs.c) +ifndef NOIDLHEADER + C_IDL += $(FILTERED_IDL:.idl=.h) +endif +OBJ_C_IDL := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ)) +AUTO_IDL := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL) + +FILTERED_OXRIDL := $(filter %.oxridl, $(FILTERED)) +DEP_OXRIDL := $(FILTERED_OXRIDL:%.oxridl=$(MLDEPDIR)/%.d) $(FILTERED_OXRIDL:.oxridl=.di) +AUTO_OXRIDL := $(FILTERED_OXRIDL:.oxridl=.mli) $(FILTERED_OXRIDL:.oxridl=.ml) $(C_OXRIDL) + +FILTERED_C_CXX := $(filter %.c %.m %.$(EXT_CXX), $(FILTERED)) +OBJ_C_CXX := $(FILTERED_C_CXX:.c=.$(EXT_OBJ)) +OBJ_C_CXX := $(OBJ_C_CXX:.m=.$(EXT_OBJ)) +OBJ_C_CXX := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ)) + +PRE_TARGETS += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) $(AUTO_OXRIDL) $(AUTO_ZOG) $(AUTO_REP) $(AUTO_GLADE) + +ALL_DEPS := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) $(DEP_OXRIDL) $(DEP_ZOG) $(DEP_REP) $(DEP_GLADE) + +MLDEPS := $(filter %.d, $(ALL_DEPS)) +MLIDEPS := $(filter %.di, $(ALL_DEPS)) +BCDEPIS := $(MLIDEPS:%.di=$(BCDIDIR)/%.di) +NCDEPIS := $(MLIDEPS:%.di=$(NCDIDIR)/%.di) + +ALLML := $(filter %.mli %.ml %.mll %.mly %.idl %.oxridl %.rep %.zog %.glade, $(FILTERED)) + +IMPLO_INTF := $(ALLML:%.mli=%.mli.__) +IMPLO_INTF := $(foreach file, $(IMPLO_INTF), \ + $(basename $(file)).cmi $(basename $(file)).cmo) +IMPLO_INTF := $(filter-out %.mli.cmo, $(IMPLO_INTF)) +IMPLO_INTF := $(IMPLO_INTF:%.mli.cmi=%.cmi) + +IMPLX_INTF := $(IMPLO_INTF:.cmo=.cmx) + +INTF := $(filter %.cmi, $(IMPLO_INTF)) +IMPL_CMO := $(filter %.cmo, $(IMPLO_INTF)) +IMPL_CMX := $(IMPL_CMO:.cmo=.cmx) +IMPL_ASM := $(IMPL_CMO:.cmo=.asm) +IMPL_S := $(IMPL_CMO:.cmo=.s) + +OBJ_LINK := $(OBJ_C_IDL) $(OBJ_C_CXX) +OBJ_FILES := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK) + +EXECS := $(addsuffix $(EXE), \ + $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT))) +ifdef WIN32 + EXECS += $(BCRESULT).dll $(NCRESULT).dll +endif + +CLIB_BASE := $(RESULT)$(RES_CLIB_SUF) +ifneq ($(strip $(OBJ_LINK)),) + RES_CLIB := lib$(CLIB_BASE).$(EXT_LIB) +endif + +ifdef WIN32 +DLLSONAME := $(CLIB_BASE).dll +else +DLLSONAME := dll$(CLIB_BASE).so +endif + +NONEXECS := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(IMPL_ASM) $(IMPL_S) \ + $(OBJ_FILES) $(PRE_TARGETS) $(BCRESULT).cma $(NCRESULT).cmxa \ + $(NCRESULT).$(EXT_LIB) $(BCRESULT).cmi $(BCRESULT).cmo \ + $(NCRESULT).cmi $(NCRESULT).cmx $(NCRESULT).o \ + $(RES_CLIB) $(IMPL_CMO:.cmo=.annot) \ + $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(LIB_PACK_NAME).cmx $(LIB_PACK_NAME).o + +ifndef STATIC + NONEXECS += $(DLLSONAME) +endif + +ifndef LIBINSTALL_FILES + LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \ + $(RESULT).cmxa $(RESULT).$(EXT_LIB) $(RES_CLIB) + ifndef STATIC + ifneq ($(strip $(OBJ_LINK)),) + LIBINSTALL_FILES += $(DLLSONAME) + endif + endif +endif + +export LIBINSTALL_FILES + +ifdef WIN32 + # some extra stuff is created while linking DLLs + NONEXECS += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp $(CLIB_BASE).exp $(CLIB_BASE).lib +endif + +TARGETS := $(EXECS) $(NONEXECS) + +# If there are IDL-files +ifneq ($(strip $(FILTERED_IDL)),) + MAYBE_IDL := -cclib -lcamlidl +endif + +ifdef USE_CAMLP4 + CAMLP4PATH := \ + $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/local/lib/camlp4) + INCFLAGS := -I $(CAMLP4PATH) + CINCFLAGS := -I$(CAMLP4PATH) +endif + +DINCFLAGS := $(INCFLAGS) $(SOURCE_DIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %) +INCFLAGS := $(DINCFLAGS) $(INCDIRS:%=-I %) +CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%) + +ifndef MSVC + CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) \ + $(EXTLIBDIRS:%=-L%) $(OCAML_DEFAULT_DIRS:%=-L%) + + ifeq ($(ELF_RPATH), yes) + CLIBFLAGS += $(EXTLIBDIRS:%=-Wl,$(RPATH_FLAG)%) + endif +endif + +ifndef PROFILING + INTF_OCAMLC := $(OCAMLC) +else + ifndef THREADS + INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS) + else + # OCaml does not support profiling byte code + # with threads (yet), therefore we force an error. + ifndef REAL_OCAMLC + $(error Profiling of multithreaded byte code not yet supported by OCaml) + endif + INTF_OCAMLC := $(OCAMLC) + endif +endif + +ifndef MSVC + COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \ + $(LIBDIRS:%=-ccopt -L%) $(EXTLIBDIRS:%=-ccopt -L%) \ + $(EXTLIBDIRS:%=-ccopt -Wl $(OCAML_DEFAULT_DIRS:%=-ccopt -L%)) + + ifeq ($(ELF_RPATH),yes) + COMMON_LDFLAGS += $(EXTLIBDIRS:%=-ccopt -Wl,$(RPATH_FLAG)%) + endif +else + COMMON_LDFLAGS := -ccopt "/link -NODEFAULTLIB:LIBC $(LDFLAGS:%=%) $(SOURCE_DIRS:%=-LIBPATH:%) \ + $(LIBDIRS:%=-LIBPATH:%) $(EXTLIBDIRS:%=-LIBPATH:%) \ + $(OCAML_DEFAULT_DIRS:%=-LIBPATH:%) " +endif + +CLIBS_OPTS := $(CLIBS:%=-cclib -l%) $(CFRAMEWORKS:%=-cclib '-framework %') +ifdef MSVC + ifndef STATIC + # MSVC libraries do not have 'lib' prefix + CLIBS_OPTS := $(CLIBS:%=-cclib %.lib) + endif +endif + +ifneq ($(strip $(OBJ_LINK)),) + ifdef CREATE_LIB + OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL) + else + OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL) + endif +else + OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL) +endif + +# If we have to make byte-code +ifndef REAL_OCAMLC + BYTE_OCAML := y + + # EXTRADEPS is added dependencies we have to insert for all + # executable files we generate. Ideally it should be all of the + # libraries we use, but it's hard to find the ones that get searched on + # the path since I don't know the paths built into the compiler, so + # just include the ones with slashes in their names. + EXTRADEPS := $(addsuffix .cma,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) + SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS) + + REAL_OCAMLC := $(INTF_OCAMLC) + + REAL_IMPL := $(IMPL_CMO) + REAL_IMPL_INTF := $(IMPLO_INTF) + IMPL_SUF := .cmo + + DEPFLAGS := + MAKE_DEPS := $(MLDEPS) $(BCDEPIS) + + ifdef CREATE_LIB + override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) + override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) + ifndef STATIC + ifneq ($(strip $(OBJ_LINK)),) + MAKEDLL := $(DLLSONAME) + ALL_LDFLAGS := -dllib $(DLLSONAME) + endif + endif + endif + + ifndef NO_CUSTOM + ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS) $(CFRAMEWORKS))" "" + ALL_LDFLAGS += -custom + endif + endif + + ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \ + $(COMMON_LDFLAGS) $(LIBS:%=%.cma) + CAMLIDLDLLFLAGS := + + ifdef THREADS + ifdef VMTHREADS + THREAD_FLAG := -vmthread + else + THREAD_FLAG := -thread + endif + ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) + ifndef CREATE_LIB + ifndef REAL_OCAMLFIND + ALL_LDFLAGS := unix.cma threads.cma $(ALL_LDFLAGS) + endif + endif + endif + +# we have to make native-code +else + EXTRADEPS := $(addsuffix .cmxa,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) + ifndef PROFILING + SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS) + PLDFLAGS := + else + SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS) + PLDFLAGS := -p + endif + + ifndef LIB_PACK_NAME + SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS) + else + SPECIAL_OCAMLFLAGS := -for-pack $(LIB_PACK_NAME) $(OCAMLNCFLAGS) + endif + REAL_IMPL := $(IMPL_CMX) + REAL_IMPL_INTF := $(IMPLX_INTF) + IMPL_SUF := .cmx + + override CPPFLAGS := -DNATIVE_CODE $(CPPFLAGS) + + DEPFLAGS := -native + MAKE_DEPS := $(MLDEPS) $(NCDEPIS) + + ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \ + $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS) + CAMLIDLDLLFLAGS := -opt + + ifndef CREATE_LIB + ALL_LDFLAGS += $(LIBS:%=%.cmxa) + else + override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) + override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) + endif + + ifdef THREADS + THREAD_FLAG := -thread + ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) + ifndef CREATE_LIB + ifndef REAL_OCAMLFIND + ALL_LDFLAGS := unix.cmxa threads.cmxa $(ALL_LDFLAGS) + endif + endif + endif +endif + +export MAKE_DEPS + +ifdef ANNOTATE + ANNOT_FLAG := -dtypes +else +endif + +ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(ANNOT_FLAG) $(OCAMLFLAGS) \ + $(INCFLAGS) $(SPECIAL_OCAMLFLAGS) + +ifdef make_deps + -include $(MAKE_DEPS) + PRE_TARGETS := +endif + +########################################################################### +# USER RULES + +# Call "OCamlMakefile QUIET=" to get rid of all of the @'s. +QUIET=@ + +# generates byte-code (default) +byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes +bc: byte-code + +byte-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(BCRESULT)" make_deps=yes +bcnl: byte-code-nolink + +top: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes + +# generates native-code + +native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +nc: native-code + +native-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +ncnl: native-code-nolink + +# generates byte-code libraries +byte-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" \ + CREATE_LIB=yes \ + make_deps=yes +bcl: byte-code-library + +# generates native-code libraries +native-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).cmxa \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + CREATE_LIB=yes \ + make_deps=yes +ncl: native-code-library + +ifdef WIN32 +# generates byte-code dll +byte-code-dll: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).dll \ + REAL_RESULT="$(BCRESULT)" \ + make_deps=yes +bcd: byte-code-dll + +# generates native-code dll +native-code-dll: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).dll \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +ncd: native-code-dll +endif + +# generates byte-code with debugging information +debug-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dc: debug-code + +debug-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dcnl: debug-code-nolink + +# generates byte-code with debugging information (native code) +debug-native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ + REAL_RESULT="$(NCRESULT)" make_deps=yes \ + REAL_OCAMLC="$(OCAMLOPT)" \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dnc: debug-native-code + +debug-native-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(NCRESULT)" make_deps=yes \ + REAL_OCAMLC="$(OCAMLOPT)" \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dncnl: debug-native-code-nolink + +# generates byte-code libraries with debugging information +debug-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + CREATE_LIB=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dcl: debug-code-library + +# generates byte-code libraries with debugging information (native code) +debug-native-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).cma \ + REAL_RESULT="$(NCRESULT)" make_deps=yes \ + REAL_OCAMLC="$(OCAMLOPT)" \ + CREATE_LIB=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dncl: debug-native-code-library + +# generates byte-code for profiling +profiling-byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" PROFILING="y" \ + make_deps=yes +pbc: profiling-byte-code + +# generates native-code + +profiling-native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + PROFILING="y" \ + make_deps=yes +pnc: profiling-native-code + +# generates byte-code libraries +profiling-byte-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" PROFILING="y" \ + CREATE_LIB=yes \ + make_deps=yes +pbcl: profiling-byte-code-library + +# generates native-code libraries +profiling-native-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).cmxa \ + REAL_RESULT="$(NCRESULT)" PROFILING="y" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + CREATE_LIB=yes \ + make_deps=yes +pncl: profiling-native-code-library + +# packs byte-code objects +pack-byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT).cmo \ + REAL_RESULT="$(BCRESULT)" \ + PACK_LIB=yes make_deps=yes +pabc: pack-byte-code + +# packs native-code objects +pack-native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(NCRESULT).cmx $(NCRESULT).o \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + PACK_LIB=yes make_deps=yes +panc: pack-native-code + +# generates HTML-documentation +htdoc: $(DOC_DIR)/$(RESULT)/html/index.html + +# generates Latex-documentation +ladoc: $(DOC_DIR)/$(RESULT)/latex/doc.tex + +# generates PostScript-documentation +psdoc: $(DOC_DIR)/$(RESULT)/latex/doc.ps + +# generates PDF-documentation +pdfdoc: $(DOC_DIR)/$(RESULT)/latex/doc.pdf + +# generates all supported forms of documentation +doc: htdoc ladoc psdoc pdfdoc + +########################################################################### +# LOW LEVEL RULES + +$(REAL_RESULT): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) \ + $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ + $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ + $(REAL_IMPL) + +nolink: $(REAL_IMPL_INTF) $(OBJ_LINK) + +ifdef WIN32 +$(REAL_RESULT).dll: $(REAL_IMPL_INTF) $(OBJ_LINK) + $(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \ + -o $@ $(REAL_IMPL) +endif + +%$(TOPSUFFIX): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) + $(REAL_OCAMLFIND) $(OCAMLMKTOP) \ + $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ + $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ + $(REAL_IMPL) + +.SUFFIXES: .mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \ + .mly .di .d .$(EXT_LIB) .idl %.oxridl .c .m .$(EXT_CXX) .h .so \ + .rep .zog .glade + +ifndef STATIC +ifdef MINGW +$(DLLSONAME): $(OBJ_LINK) + $(CC) $(CFLAGS) $(CFLAGS_WIN32) $(OBJ_LINK) -shared -o $@ \ + -Wl,--whole-archive $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/lib%.a))) \ + $(OCAMLLIBPATH)/ocamlrun.a \ + -Wl,--export-all-symbols \ + -Wl,--no-whole-archive +else +ifdef MSVC +$(DLLSONAME): $(OBJ_LINK) + link /NOLOGO /DLL /OUT:$@ $(OBJ_LINK) \ + $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/%.lib))) \ + $(OCAMLLIBPATH)/ocamlrun.lib + +else +$(DLLSONAME): $(OBJ_LINK) + $(OCAMLMKLIB) $(INCFLAGS) $(CLIBFLAGS) \ + -o $(CLIB_BASE) $(OBJ_LINK) $(CLIBS:%=-l%) $(CFRAMEWORKS:%=-framework %) \ + $(OCAMLMKLIB_FLAGS) +endif +endif +endif + +ifndef LIB_PACK_NAME +$(RESULT).cma: $(REAL_IMPL_INTF) $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@ $(REAL_IMPL) + +$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(REAL_IMPL_INTF) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@ $(REAL_IMPL) +else +# Packing a bytecode library +ifdef BYTE_OCAML +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo: $(REAL_IMPL_INTF) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmo $(OCAMLLDFLAGS) $(REAL_IMPL) +# Packing into a unit which can be transformed into a library +# Remember the .ml's must have been compiled with -for-pack $(LIB_PACK_NAME) +else +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx: $(REAL_IMPL_INTF) + $(REAL_OCAMLFIND) $(OCAMLOPT) -pack -o $(LIB_PACK_NAME).cmx $(OCAMLLDFLAGS) $(REAL_IMPL) +endif + +$(RESULT).cma: $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@ $(LIB_PACK_NAME).cmo + +$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(filter-out -custom, $(ALL_LDFLAGS)) $(OBJS_LIBS) -o $@ $(LIB_PACK_NAME).cmx +endif + +$(RES_CLIB): $(OBJ_LINK) +ifndef MSVC + ifneq ($(strip $(OBJ_LINK)),) + $(AR) rcs $@ $(OBJ_LINK) + endif +else + ifneq ($(strip $(OBJ_LINK)),) + lib -nologo -debugtype:cv -out:$(RES_CLIB) $(OBJ_LINK) + endif +endif + +.mli.cmi: $(EXTRADEPS) + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + $(ECHO) $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + else \ + $(ECHO) $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp \"$$pp $(PPFLAGS)\" $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp "$$pp $(PPFLAGS)" $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + fi + +.ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: $(EXTRADEPS) + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + $(ECHO) $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(ALL_OCAMLCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(ALL_OCAMLCFLAGS) $<; \ + else \ + $(ECHO) $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp \"$$pp $(PPFLAGS)\" $(ALL_OCAMLCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp "$$pp $(PPFLAGS)" $(ALL_OCAMLCFLAGS) $<; \ + fi + +ifdef PACK_LIB +$(REAL_RESULT).cmo $(REAL_RESULT).cmx $(REAL_RESULT).o: $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack $(ALL_LDFLAGS) \ + $(OBJS_LIBS) -o $@ $(REAL_IMPL) +endif + +.PRECIOUS: %.ml +%.ml: %.mll + $(OCAMLLEX) $(LFLAGS) $< + +.PRECIOUS: %.ml %.mli +%.ml %.mli: %.mly + $(OCAMLYACC) $(YFLAGS) $< + $(QUIET)pp=`sed -n -e 's/.*(\*pp \([^*]*\) \*).*/\1/p;q' $<`; \ + if [ ! -z "$$pp" ]; then \ + mv $*.ml $*.ml.temporary; \ + echo "(*pp $$pp $(PPFLAGS)*)" > $*.ml; \ + cat $*.ml.temporary >> $*.ml; \ + rm $*.ml.temporary; \ + mv $*.mli $*.mli.temporary; \ + echo "(*pp $$pp $(PPFLAGS)*)" > $*.mli; \ + cat $*.mli.temporary >> $*.mli; \ + rm $*.mli.temporary; \ + fi + + +.PRECIOUS: %.ml +%.ml: %.rep + $(CAMELEON_REPORT) $(CAMELEON_REPORT_FLAGS) -gen $< + +.PRECIOUS: %.ml +%.ml: %.zog + $(CAMELEON_ZOGGY) $(CAMELEON_ZOGGY_FLAGS) -impl $< > $@ + +.PRECIOUS: %.ml +%.ml: %.glade + $(OCAML_GLADECC) $(OCAML_GLADECC_FLAGS) $< > $@ + +.PRECIOUS: %.ml %.mli +%.ml %.mli: %.oxridl + $(OXRIDL) $< + +.PRECIOUS: %.ml %.mli %_stubs.c %.h +%.ml %.mli %_stubs.c %.h: %.idl + $(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \ + $(CAMLIDLFLAGS) $< + $(QUIET)if [ $(NOIDLHEADER) ]; then touch $*.h; fi + +.c.$(EXT_OBJ): + $(OCAMLC) -c -cc "$(CC)" -ccopt "$(CFLAGS) \ + $(CPPFLAGS) $(CPPFLAGS_WIN32) \ + $(CFLAGS_WIN32) $(CINCFLAGS) $(CFLAG_O)$@ " $< + +.m.$(EXT_OBJ): + $(CC) -c $(CFLAGS) $(CINCFLAGS) $(CPPFLAGS) \ + -I'$(OCAMLLIBPATH)' \ + $< $(CFLAG_O)$@ + +.$(EXT_CXX).$(EXT_OBJ): + $(CXX) -c $(CXXFLAGS) $(CINCFLAGS) $(CPPFLAGS) \ + -I'$(OCAMLLIBPATH)' \ + $< $(CFLAG_O)$@ + +$(MLDEPDIR)/%.d: %.ml + $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + $(ECHO) $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + $(DINCFLAGS) $< > $@; \ + else \ + $(ECHO) $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ + fi + +$(BCDIDIR)/%.di $(NCDIDIR)/%.di: %.mli + $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + $(ECHO) $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< > $@; \ + else \ + $(ECHO) $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ + -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ + -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ + fi + +$(DOC_DIR)/$(RESULT)/html: + mkdir -p $@ + +$(DOC_DIR)/$(RESULT)/html/index.html: $(DOC_DIR)/$(RESULT)/html $(DOC_FILES) + rm -rf $= 4.00.0 -FindlibVersion: >= 1.3.2 -Name: async_ssl -Version: 111.08.00 -Synopsis: Async wrappers for ssl -Authors: Jane Street Capital LLC -Copyrights: (C) 2008-2013 Jane Street Capital LLC -Maintainers: Jane Street Capital LLC -License: Apache-2.0 -LicenseFile: LICENSE.txt -Homepage: https://github.com/janestreet/async -Plugins: StdFiles (0.3), DevFiles (0.3), META (0.3) -XStdFilesAUTHORS: false -XStdFilesREADME: false -BuildTools: ocamlbuild, camlp4o -Description: - An Async-pipe-based interface with OpenSSL. - . - This library allows you to create an SSL client and server, with encrypted - communication between both. - -Library async_ssl - Path: lib - FindlibName: async_ssl - Pack: true - Modules: Ffi_bindings, - Ffi, - Import, - Ssl, - Std, - Version - BuildDepends: core, - async, - ctypes, - ctypes.foreign, - herelib, - herelib.syntax, - pa_bench, - pa_bench.syntax, - pa_ounit, - pa_ounit.syntax, - sexplib, - sexplib.syntax, - threads - XMETARequires: core, - async, - ctypes, - ctypes.foreign, - herelib, - pa_bench, - pa_bench.syntax, - pa_ounit, - sexplib, - threads - CCLib: -lssl -lcrypto diff --git a/_tags b/_tags deleted file mode 100644 index 4947002..0000000 --- a/_tags +++ /dev/null @@ -1,3 +0,0 @@ -<**/*.ml{,i}> : syntax_camlp4o -# OASIS_START -# OASIS_STOP diff --git a/configure b/configure deleted file mode 100755 index 3234be2..0000000 --- a/configure +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# OASIS_START -make configure CONFIGUREFLAGS="$*" -# OASIS_STOP diff --git a/setup.ml b/setup.ml deleted file mode 100644 index 2d84529..0000000 --- a/setup.ml +++ /dev/null @@ -1,8 +0,0 @@ -(* OASIS_START *) -#use "topfind";; -#require "oasis.dynrun";; -open OASISDynRun;; -open OASISTypes;; -(* OASIS_STOP *) - -let () = setup () From 667082cf95e4c2765f0f7dc7dd9e8b803b7fd60f Mon Sep 17 00:00:00 2001 From: Jeremy Yallop Date: Thu, 10 Apr 2014 10:37:15 +0100 Subject: [PATCH 3/8] Switch from ctypes.foreign to ctypes.stubs. C stubs (and the corresponding OCaml wrapper) are now generated in an early stage of compilation, then linked into the library. There's no longer a dependency on libffi. --- META | 2 +- Makefile | 85 ++++++++++++++++-------- lib/ffi.ml | 2 +- lib/ffi_bindings.ml | 147 +++++++++++++++++++++--------------------- lib/ffi_generated.mli | 2 + lib/ffi_stubgen.ml | 24 +++++++ 6 files changed, 160 insertions(+), 102 deletions(-) create mode 100644 lib/ffi_generated.mli create mode 100644 lib/ffi_stubgen.ml diff --git a/META b/META index 52e017c..cd94a64 100644 --- a/META +++ b/META @@ -1,7 +1,7 @@ version = "111.08.00" description = "Async wrappers for ssl" requires = -"core async ctypes ctypes.foreign herelib pa_bench pa_bench.syntax pa_ounit sexplib threads" +"threads core async ctypes ctypes.stubs herelib pa_bench pa_bench.syntax pa_ounit sexplib" archive(byte) = "async_ssl.cma" archive(byte, plugin) = "async_ssl.cma" archive(native) = "async_ssl.cmxa" diff --git a/Makefile b/Makefile index 47b4503..d5f76bf 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,57 @@ -USE_CAMLP4=yes - -PACKS=sexplib.syntax,sexplib,pa_ounit.syntax,pa_ounit,pa_bench.syntax,pa_bench,herelib.syntax,herelib,ctypes.foreign,ctypes,async,core - -CLIBS=ssl crypto - -OCAMLDEP = ocamldep -package $(PACKS) -syntax camlp4o -OCAMLFLAGS = -syntax camlp4o -thread -RESULT=async_ssl -LIB_PACK_NAME=Async_ssl - -SOURCES=lib/import.ml \ - lib/version.ml lib/version.mli \ - lib/ffi_bindings.ml \ - lib/ffi.ml lib/ffi.mli \ - lib/ssl.ml lib/ssl.mli \ - lib/std.ml - -LIBINSTALL_FILES = lib/ffi.mli lib/ssl.mli lib/version.mli \ - Async_ssl.cmi Async_ssl.cmo Async_ssl.cmx \ - async_ssl.cma async_ssl.cmxa async_ssl.a \ - META - -all: byte-code-library native-code-library - -install: libinstall - --include OCamlMakefile +export USE_CAMLP4=yes +export OCAMLMAKEFILE = ./OCamlMakefile +export THREADS=yes +export PACKS=sexplib.syntax,sexplib,pa_ounit.syntax,pa_ounit,pa_bench.syntax,\ +pa_bench,herelib.syntax,herelib,ctypes.stubs,async,core +export LIB_PACK_NAME=Async_ssl +export CLIBS=ssl crypto +export OCAMLDEP = ocamldep -package $(PACKS) -syntax camlp4o +export OCAMLFLAGS = -syntax camlp4o +export LIBINSTALL_FILES = lib/ffi.mli lib/ssl.mli lib/version.mli \ + Async_ssl.cmi Async_ssl.cmo Async_ssl.cmx \ + async_ssl.cma async_ssl.cmxa async_ssl.a \ + META + +ifndef SUBPROJS + export SUBPROJS = stubgen async_ssl +endif + +define PROJ_stubgen + RESULT=stubgen + SOURCES=lib/import.ml \ + lib/version.ml lib/version.mli \ + lib/ffi_bindings.ml \ + lib/ffi_stubgen.ml +endef +export PROJ_stubgen + +define PROJ_async_ssl + RESULT=async_ssl + INCDIRS = $(shell ocamlc -where)/.. foo + SOURCES=lib/import.ml \ + lib/version.ml lib/version.mli \ + lib/ffi_bindings.ml \ + lib/ffi_generated.ml lib/ffi_generated.mli \ + lib/ffi_generated_stubs.c \ + lib/ffi.ml lib/ffi.mli \ + lib/ssl.ml lib/ssl.mli \ + lib/std.ml +endef +export PROJ_async_ssl + +all: stubs byte-code-library native-code-library + +install: all + ocamlfind install async_ssl $(LIBINSTALL_FILES) +uninstall: + ocamlfind remove async_ssl + +stubgen: SUBPROJS=stubgen +stubgen: nc + +stubs: stubgen + ./$< -ml > lib/ffi_generated.ml + ./$< -c > lib/ffi_generated_stubs.c + +%: + @$(MAKE) -f $(OCAMLMAKEFILE) subprojs SUBTARGET=$@ diff --git a/lib/ffi.ml b/lib/ffi.ml index 2e46f6c..623bbf5 100644 --- a/lib/ffi.ml +++ b/lib/ffi.ml @@ -2,7 +2,7 @@ open Core.Std open Async.Std open Import -module Bindings = Ffi_bindings +module Bindings = Ffi_bindings.Bindings(Ffi_generated) module Ssl_error = struct type t = diff --git a/lib/ffi_bindings.ml b/lib/ffi_bindings.ml index 9119e34..2881b14 100644 --- a/lib/ffi_bindings.ml +++ b/lib/ffi_bindings.ml @@ -1,105 +1,108 @@ -let foreign = Foreign.foreign +module Bindings (F : Cstubs.FOREIGN) = +struct + let foreign = F.foreign -let err_get_error = foreign "ERR_get_error" - Ctypes.(void @-> returning ulong) + let err_get_error = foreign "ERR_get_error" + Ctypes.(void @-> returning ulong) -let err_error_string_n = foreign "ERR_error_string_n" - Ctypes.(ulong @-> ptr char @-> int @-> returning void) + let err_error_string_n = foreign "ERR_error_string_n" + Ctypes.(ulong @-> ptr char @-> int @-> returning void) -let add_all_digests = foreign "OpenSSL_add_all_digests" - Ctypes.(void @-> returning void) + let add_all_digests = foreign "OpenSSL_add_all_digests" + Ctypes.(void @-> returning void) -let add_all_ciphers = foreign "OpenSSL_add_all_ciphers" - Ctypes.(void @-> returning void) + let add_all_ciphers = foreign "OpenSSL_add_all_ciphers" + Ctypes.(void @-> returning void) -let init = foreign "SSL_library_init" - Ctypes.(void @-> returning ulong) + let init = foreign "SSL_library_init" + Ctypes.(void @-> returning ulong) -let ssl_load_error_strings = foreign "SSL_load_error_strings" - Ctypes.(void @-> returning void) + let ssl_load_error_strings = foreign "SSL_load_error_strings" + Ctypes.(void @-> returning void) -let ssl_method_t = Ctypes.(void @-> returning (ptr void)) -let sslv3_method = foreign "SSLv3_method" ssl_method_t -let tlsv1_method = foreign "TLSv1_method" ssl_method_t -let sslv23_method = foreign "SSLv23_method" ssl_method_t -(* SSLv2 isn't secure, so we don't use it. If you really really really need it, use - SSLv23 which will at least try to upgrade the security whenever possible. + let ssl_method_t = Ctypes.(void @-> returning (ptr void)) + let sslv3_method = foreign "SSLv3_method" ssl_method_t + let tlsv1_method = foreign "TLSv1_method" ssl_method_t + let sslv23_method = foreign "SSLv23_method" ssl_method_t + (* SSLv2 isn't secure, so we don't use it. If you really really really need it, use + SSLv23 which will at least try to upgrade the security whenever possible. - let sslv2_method = foreign "SSLv2_method" ssl_method_t -*) + let sslv2_method = foreign "SSLv2_method" ssl_method_t + *) -module Ssl_ctx = -struct - let t = Ctypes.(ptr void) + module Ssl_ctx = + struct + let t = Ctypes.(ptr void) - let ssl_ctx_new = foreign "SSL_CTX_new" - Ctypes.(ptr void @-> returning (ptr_opt void)) + let ssl_ctx_new = foreign "SSL_CTX_new" + Ctypes.(ptr void @-> returning (ptr_opt void)) - let ssl_ctx_free = foreign "SSL_CTX_free" - Ctypes.(t @-> returning void) + let ssl_ctx_free = foreign "SSL_CTX_free" + Ctypes.(t @-> returning void) - let ssl_ctx_load_verify_locations = foreign "SSL_CTX_load_verify_locations" - Ctypes.(t @-> string_opt @-> string_opt @-> returning int) -end + let ssl_ctx_load_verify_locations = foreign "SSL_CTX_load_verify_locations" + Ctypes.(t @-> string_opt @-> string_opt @-> returning int) + end -module Bio = -struct - let t = Ctypes.(ptr void) (* for use in ctypes signatures *) + module Bio = + struct + let t = Ctypes.(ptr void) (* for use in ctypes signatures *) - let bio_new = foreign "BIO_new" - Ctypes.(ptr void @-> returning t) + let bio_new = foreign "BIO_new" + Ctypes.(ptr void @-> returning t) - let bio_s_mem = foreign "BIO_s_mem" - Ctypes.(void @-> returning (ptr void)) + let bio_s_mem = foreign "BIO_s_mem" + Ctypes.(void @-> returning (ptr void)) - let bio_read = foreign "BIO_read" - Ctypes.(t @-> ptr char @-> int @-> returning int) + let bio_read = foreign "BIO_read" + Ctypes.(t @-> ptr char @-> int @-> returning int) - let bio_write = foreign "BIO_write" - Ctypes.(t @-> string @-> int @-> returning int) -end + let bio_write = foreign "BIO_write" + Ctypes.(t @-> string @-> int @-> returning int) + end -module Ssl = -struct - let t = Ctypes.(ptr void) + module Ssl = + struct + let t = Ctypes.(ptr void) - let ssl_new = foreign "SSL_new" - Ctypes.(Ssl_ctx.t @-> returning t) + let ssl_new = foreign "SSL_new" + Ctypes.(Ssl_ctx.t @-> returning t) - let ssl_free = foreign "SSL_free" - Ctypes.(t @-> returning void) + let ssl_free = foreign "SSL_free" + Ctypes.(t @-> returning void) - let ssl_set_method = foreign "SSL_set_ssl_method" - Ctypes.(t @-> ptr void @-> returning int) + let ssl_set_method = foreign "SSL_set_ssl_method" + Ctypes.(t @-> ptr void @-> returning int) - let ssl_get_error = foreign "SSL_get_error" - Ctypes.(ptr void @-> int @-> returning int) + let ssl_get_error = foreign "SSL_get_error" + Ctypes.(ptr void @-> int @-> returning int) - let ssl_set_connect_state = foreign "SSL_set_connect_state" - Ctypes.(t @-> returning void) + let ssl_set_connect_state = foreign "SSL_set_connect_state" + Ctypes.(t @-> returning void) - let ssl_set_accept_state = foreign "SSL_set_accept_state" - Ctypes.(t @-> returning void) + let ssl_set_accept_state = foreign "SSL_set_accept_state" + Ctypes.(t @-> returning void) - let ssl_connect = foreign "SSL_connect" - Ctypes.(t @-> returning int) + let ssl_connect = foreign "SSL_connect" + Ctypes.(t @-> returning int) - let ssl_accept = foreign "SSL_accept" - Ctypes.(t @-> returning int) + let ssl_accept = foreign "SSL_accept" + Ctypes.(t @-> returning int) - let ssl_set_bio = foreign "SSL_set_bio" - Ctypes.(t @-> Bio.t @-> Bio.t @-> returning void) + let ssl_set_bio = foreign "SSL_set_bio" + Ctypes.(t @-> Bio.t @-> Bio.t @-> returning void) - let ssl_read = foreign "SSL_read" - Ctypes.(t @-> ptr char @-> int @-> returning int) + let ssl_read = foreign "SSL_read" + Ctypes.(t @-> ptr char @-> int @-> returning int) - let ssl_write = foreign "SSL_write" - Ctypes.(t @-> string @-> int @-> returning int) + let ssl_write = foreign "SSL_write" + Ctypes.(t @-> string @-> int @-> returning int) - let ssl_use_certificate_file = foreign "SSL_use_certificate_file" - Ctypes.(t @-> string @-> int @-> returning int) + let ssl_use_certificate_file = foreign "SSL_use_certificate_file" + Ctypes.(t @-> string @-> int @-> returning int) - let ssl_use_private_key_file = foreign "SSL_use_PrivateKey_file" - Ctypes.(t @-> string @-> int @-> returning int) + let ssl_use_private_key_file = foreign "SSL_use_PrivateKey_file" + Ctypes.(t @-> string @-> int @-> returning int) + end end diff --git a/lib/ffi_generated.mli b/lib/ffi_generated.mli new file mode 100644 index 0000000..74d6b18 --- /dev/null +++ b/lib/ffi_generated.mli @@ -0,0 +1,2 @@ +type 'a fn = 'a +val foreign : string -> ('a -> 'b) Ctypes.fn -> ('a -> 'b) diff --git a/lib/ffi_stubgen.ml b/lib/ffi_stubgen.ml new file mode 100644 index 0000000..9f519ba --- /dev/null +++ b/lib/ffi_stubgen.ml @@ -0,0 +1,24 @@ +let prefix = "async_ssl_stub" + +let prologue = " +#include +#include +" + +let () = + let generate_ml, generate_c = ref false, ref false in + let () = + Arg.(parse [ ("-ml", Set generate_ml, "Generate ML"); + ("-c", Set generate_c, "Generate C") ]) + (fun _ -> failwith "unexpected anonymous argument") + "stubgen [-ml|-c]" + in + match !generate_ml, !generate_c with + | false, false + | true, true -> + failwith "Exactly one of -ml and -c must be specified" + | true, false -> + Cstubs.write_ml Format.std_formatter ~prefix (module Ffi_bindings.Bindings) + | false, true -> + print_endline prologue; + Cstubs.write_c Format.std_formatter ~prefix (module Ffi_bindings.Bindings) From 225623e74b27ae2e44088d35b740356f6b20f810 Mon Sep 17 00:00:00 2001 From: Jeremy Yallop Date: Thu, 10 Apr 2014 11:42:25 +0100 Subject: [PATCH 4/8] Update path to ctypes headers. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d5f76bf..24f3fcb 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ export PROJ_stubgen define PROJ_async_ssl RESULT=async_ssl - INCDIRS = $(shell ocamlc -where)/.. foo + INCDIRS = $(shell ocamlfind query ctypes)/.. SOURCES=lib/import.ml \ lib/version.ml lib/version.mli \ lib/ffi_bindings.ml \ From a18caf23487eb906e5a92c619277d9b41577c5f4 Mon Sep 17 00:00:00 2001 From: Anil Madhavapeddy Date: Thu, 10 Apr 2014 11:48:34 +0100 Subject: [PATCH 5/8] include `` to define `ERR_get_error` --- lib/ffi_stubgen.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ffi_stubgen.ml b/lib/ffi_stubgen.ml index 9f519ba..2d77fdf 100644 --- a/lib/ffi_stubgen.ml +++ b/lib/ffi_stubgen.ml @@ -2,6 +2,7 @@ let prefix = "async_ssl_stub" let prologue = " #include +#include #include " From 7a9ea928f03a75107f6fdfd2865b83f970f7d197 Mon Sep 17 00:00:00 2001 From: Anil Madhavapeddy Date: Thu, 10 Apr 2014 12:09:15 +0100 Subject: [PATCH 6/8] Add CFLAGS to C stub build Disable deprecation warnings for now, but revisit in the near future... --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 24f3fcb..101fe51 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ export USE_CAMLP4=yes export OCAMLMAKEFILE = ./OCamlMakefile export THREADS=yes +export CFLAGS=-Wall -Wno-deprecated-declarations export PACKS=sexplib.syntax,sexplib,pa_ounit.syntax,pa_ounit,pa_bench.syntax,\ pa_bench,herelib.syntax,herelib,ctypes.stubs,async,core export LIB_PACK_NAME=Async_ssl From 20460873d2d1ceb02e7408265ca956264f8e14b3 Mon Sep 17 00:00:00 2001 From: Anil Madhavapeddy Date: Thu, 10 Apr 2014 12:09:36 +0100 Subject: [PATCH 7/8] Install the stub libraries as well --- META | 3 +-- Makefile | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/META b/META index cd94a64..2692dd9 100644 --- a/META +++ b/META @@ -1,7 +1,6 @@ version = "111.08.00" description = "Async wrappers for ssl" -requires = -"threads core async ctypes ctypes.stubs herelib pa_bench pa_bench.syntax pa_ounit sexplib" +requires = "threads core async ctypes ctypes.stubs herelib pa_bench pa_bench.syntax pa_ounit sexplib" archive(byte) = "async_ssl.cma" archive(byte, plugin) = "async_ssl.cma" archive(native) = "async_ssl.cmxa" diff --git a/Makefile b/Makefile index 101fe51..8d55b50 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ export OCAMLFLAGS = -syntax camlp4o export LIBINSTALL_FILES = lib/ffi.mli lib/ssl.mli lib/version.mli \ Async_ssl.cmi Async_ssl.cmo Async_ssl.cmx \ async_ssl.cma async_ssl.cmxa async_ssl.a \ + libasync_ssl_stubs.a dllasync_ssl_stubs.so \ META ifndef SUBPROJS From 7b456a5462ceef644ad9e51ba70762c5686eccf9 Mon Sep 17 00:00:00 2001 From: Anil Madhavapeddy Date: Tue, 27 May 2014 22:54:58 +0100 Subject: [PATCH 8/8] Add gitignore for the Make-based build --- .gitignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53902d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.a +*.o +*.cmx +*.cmxa +*.cmo +*.cmi +*.so +*.cma +._bcdi/ +._d/ +._ncdi/ +.*.swp +stubgen +lib/ffi_generated.ml +lib/ffi_generated_stubs.c