CC=@CC@
CFLAGS_OPT = -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized -fcommon
CFLAGS_OPT += ${CPPFLAGS}
CFLAGS = -O2 -fPIC $(CFLAGS_OPT) -I@OCAMLLIB@
CFLAGS_DBG = -g -fPIC -I@OCAMLLIB@ $(CFLAGS_OPT)
caml_link_dirs = @OCAMLLIB@
LDFLAGS = -cclib -L$(caml_link_dirs) -cclib -lcamlidl

all:	@idl_gen@
	$(CC) @srcdir@/pkcs11_stubs.c -DSERVER_ROLE -c $(CFLAGS)
	$(CC) @srcdir@/pkcs11_functions.c @aliasing_def@ -DSERVER_ROLE -c $(CFLAGS)
	ocamlopt @ocaml_options@ -pp "camlp4o pa_macro.cmo @ocaml_bytes_module_define@" -o pkcs11 -c @srcdir@/pkcs11.mli
	ocamlopt @ocaml_options@ -pp "camlp4o pa_macro.cmo @ocaml_bytes_module_define@" -o pkcs11 -c @srcdir@/pkcs11.ml
	ocamlmklib -o pkcs11 pkcs11.cmx pkcs11_functions.o pkcs11_stubs.o $(LDFLAGS)

debug:	@idl_gen@
	$(CC) @srcdir@/pkcs11_stubs.c -DSERVER_ROLE -DDEBUG -g -c $(CFLAGS_DBG)
	$(CC) @srcdir@/pkcs11_functions.c @aliasing_def@ -DSERVER_ROLE -g -DDEBUG -c $(CFLAGS_DBG)
	ocamlopt @ocaml_options@ -pp "camlp4o pa_macro.cmo @ocaml_bytes_module_define@" -g -o pkcs11 -c @srcdir@/pkcs11.mli
	ocamlopt @ocaml_options@ -pp "camlp4o pa_macro.cmo @ocaml_bytes_module_define@" -g -o pkcs11 -c @srcdir@/pkcs11.ml
	ocamlmklib -o pkcs11 pkcs11.cmx pkcs11_functions.o pkcs11_stubs.o $(LDFLAGS)

idl:
	@rm -f @idl_clean@
	camlidl @idl_ocaml_bytes_module_define@ -header @srcdir@/pkcs11.idl
	cat @srcdir@/pkcs11_stubs.c | sed -e 's/Begin_roots_block(\(.*\)).*/Begin_roots_block(\1);/g' | sed -e 's/Begin_root(\(.*\)).*/Begin_root(\1);/g' | sed -e 's/End_roots(\(.*\)).*/End_roots(\1);/g' > ./tmp
	mv ./tmp @srcdir@/pkcs11_stubs.c
	#Sed to patch (GetSlotList/GetMechList/FindObjects/GetObjectSize)
	sed -i "s/* int/\* nativeint/g" @srcdir@/pkcs11.mli
	sed -i "s/* int/\* nativeint/g" @srcdir@/pkcs11.ml
	#Handle recent IDL (as they rename some functions and cocci patches will not be applied otherwise)
	sed -i "s/caml_modify/modify/g" @srcdir@/pkcs11_stubs.c
	sed -i "s/caml_copy_nativeint/custom_copy_int/g" @srcdir@/pkcs11_stubs.c
	sed -i "s/caml_invalid_argument/invalid_argument/g" @srcdir@/pkcs11_stubs.c
	# Patch the stubs with cocci
	spatch --no-show-diff --in-place --sp-file @srcdir@/pkcs11_stubs.cocci @srcdir@/pkcs11_stubs.c
	#Sed because spatch is not able to preprocess
	sed -i 's/^_CAMLIDL_EXTERN_C/extern/g' @srcdir@/pkcs11.h
	#Sed to change the structure packing pragma in WIN32 mode: CamlIDL fixes it to 8 while
	#PKCS11 header fixes it to 1 => this can create binary interoperability issues
	sed -i 's/push,8/push,1\/* Replaced for PKCS11 compatibiliy *\//g' @srcdir@/pkcs11.h
	spatch --no-show-diff --in-place --sp-file @srcdir@/@pkcs11_cocci_patch@ @srcdir@/pkcs11.h
	#Sed to force the produced idl variable context and some values to be tagged 'unused'
	sed -i 's/\(.*\), camlidl_ctx _ctx)$$/#ifdef __GNUC__\n\1, __attribute__((unused)) camlidl_ctx _ctx)\n#else\n\1, camlidl_ctx _ctx)\n#endif/g' @srcdir@/pkcs11_stubs.c
	sed -i 's/\(.*\)value _unit)$$/#ifdef __GNUC__\n\1__attribute__((unused))value _unit)\n#else\n\1value _unit)\n#endif/g' @srcdir@/pkcs11_stubs.c
	#Sed to disable the warnings on shadowing caml__roots_block
	sed -i 's/\(.*\)Begin_root(\(.*\)/\/* We add this because of possible shadow warning  *\/\n\/* (this is not our code: these are camlidl macros)*\/\n#if GCC_VERSION > 40600\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n\1Begin_root(\2\n#if GCC_VERSION > 40600\n#pragma GCC diagnostic pop\n#endif/g' @srcdir@/pkcs11_stubs.c
	sed -i 's/\(.*\)Begin_roots_block(\(.*\)/\/* We add this because of possible shadow warning  *\/\n\/* (this is not our code: these are camlidl macros)*\/\n#if GCC_VERSION > 40600\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n\1Begin_roots_block(\2\n#if GCC_VERSION > 40600\n#pragma GCC diagnostic pop\n#endif/g' @srcdir@/pkcs11_stubs.c

clean_idl:
	@rm -f @srcdir@/pkcs11.h @srcdir@/pkcs11_stubs.c @srcdir@/pkcs11.mli @srcdir@/pkcs11.ml
clean:
	@rm -f @srcdir@/*.cmi @srcdir@/*.cmx @srcdir@/*.o @srcdir@/*.cmo @srcdir@/*~ @srcdir@/*.opt @srcdir@/*.cmxa @srcdir@/*.a @srcdir@/*.cma @srcdir@/*.so
