Commits

Zachary Anderson committed 2e6ea55

Switching over to CMake for the whole build. This commit may fail to build

Comments (0)

Files changed (27)

 config.status
 config.log
 
+build
+
 *~
 *.exe
 *.d
 *.cma
 *.cmxa
 *.dylib
+*.pyc
 
 bu*.*
 *.aux
 autom4te.cache/*
 ciltut-lib/Makefile.dummy
 ciltut-lib/src/config.h
+ciltut-lib/install_manifest.txt
 ciltut-lib/src/*.tex
 test/*.tex
 cil_tutorial.*
 
-ciltut-lib/CMakeCache.txt
-ciltut-lib/CMakeFiles/*
-ciltut-lib/Makefile
-ciltut-lib/cmake_install.cmake
-ciltut-lib/src/CMakeFiles/*
-ciltut-lib/src/Makefile
-ciltut-lib/src/cmake_install.cmake
+tools/delcamlcomms
+tools/pygCext/pygCext.egg-info
+tools/pygCext/build
+tools/pygCext/dist
 
-tools/delcamlcomms
-
+docs/ciltut.mw
+cmake_minimum_required(VERSION 2.6)
+project(cil-template)
+
+include(CheckLibraryExists)
+
+if(NOT DEFINED CMAKE_ISNTALL_PREFIX)
+set(CMAKE_INSTALL_PREFIX "/usr/local/lib/ciltut/")
+endif()
+
+if(NOT DEFINED BUILD_TUT11)
+set(BUILD_TUT11 false)
+endif()
+
+if(NOT DEFINED BUILD_TUT15)
+set(BUILD_TUT15 false)
+endif()
+
+list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules/")
+
+check_library_exists(rt clock_gettime "" HAVE_RT_L)
+check_library_exists(dl dlopen "" HAVE_DL_L)
+
+# No optimization
+#set(CMAKE_C_FLAGS "-Wall -Werror -Og -ggdb")
+#set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Werror -Og -ggdb")
+
+# Full optimization
+set(CMAKE_C_FLAGS "-flto -Wall -Werror -O3")
+set(CMAKE_CXX_FLAGS "-flto -std=c++0x -Wall -Werror -O3")
+set(CMAKE_EXE_LINKER_FLAGS "-flto -fuse-linker-plugin")
+
+# use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+
+# when building, don't use the install RPATH already
+# (but later on when installing)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
+
+SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+# add the automatically determined parts of the RPATH
+# which point to directories outside the build tree to the install RPATH
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+find_package(OCaml REQUIRED)
+include(UseOCaml)
+
+set(CILTUT_SRC src/tututil
+               src/ciltutoptions
+               src/tut0
+               src/tut1
+               src/tut2
+               src/tut3
+               src/tut4
+               src/tut5
+               src/tut6
+               src/tut7
+               src/tut8
+               src/tut9
+               src/tut10
+               src/tut11
+               src/tut12
+               src/tut13
+               src/tut14
+               src/tut15
+               src/main)
+
+set(CILTUT_PACKS unix str ocamlgraph cil)
+
+if(BUILD_TUT11 STREQUAL "true")
+  set(PPARGS "${PPARGS} -DBUILD_TUT11")
+  list(APPEND CILTUT_PACKS dynlink)
+  list(APPEND CILTUT_PACKS why3)
+endif()
+
+if(BUILD_TUT15 STREQUAL "true")
+  set(PPARGS "${PPARGS} -DBUILD_TUT15")
+endif()
+
+message("isntall prefix = " ${CMAKE_INSTALL_PREFIX})
+message("PPARGS = " ${PPARGS})
+
+foreach(PACK ${CILTUT_PACKS})
+  find_ocaml_package(${PACK})
+endforeach()
+
+add_ocaml_executable(ciltutcc.exe
+                     OCAMLOPTS -pp "camlp4o pa_macro.cmo ${PPARGS}"
+                     OCAMLCOPTS -pp "camlp4o pa_macro.cmo ${PPARGS}"
+                     SOURCES ${CILTUT_SRC}
+                     PACKAGES ${CILTUT_PACKS})
+
+add_subdirectory(ciltut-lib)
+
+install_ocaml_executable(ciltutcc.exe)
+install(PROGRAMS ${PROJECT_SOURCE_DIR}/bin/ciltutcc DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/lib/Ciltut.pm DESTINATION lib)
+install(FILES ${PROJECT_SOURCE_DIR}/ciltut-include/ciltut.h DESTINATION include)
+
+# make a symlink in /usr/local/bin
+if(CMAKE_HOST_UNIX)
+    install(CODE "
+    EXECUTE_PROCESS(COMMAND
+        ${CMAKE_COMMAND} -E create_symlink
+          ${CMAKE_INSTALL_PREFIX}/bin/ciltutcc
+          /usr/local/bin/ciltutcc
+       WORKING_DIRECTORY /
+       )
+    ")
+endif(CMAKE_HOST_UNIX)

CMakeModules/FindOCaml.cmake

+# Find OCaml binaries.
+
+include( FindPackageHandleStandardArgs )
+
+# find base ocaml binary
+find_program( CMAKE_OCAML_OCAML
+    NAMES ocaml
+    )
+# get the directory, used for hints for the rest of the binaries
+if( CMAKE_OCAML_OCAML )
+    get_filename_component( OCAML_ROOT_DIR ${CMAKE_OCAML_OCAML} PATH )
+endif()
+
+# ocamlfind
+find_program( CMAKE_OCAML_OCAMLFIND
+    NAMES ocamlfind ocamlfind_opt
+    HINTS ${OCAML_ROOT_DIR}
+    )
+
+if( CMAKE_OCAML_OCAMLFIND )
+    execute_process(
+        COMMAND ${CMAKE_OCAML_OCAMLFIND} ocamlc -version
+        OUTPUT_VARIABLE CMAKE_OCAML_VERSION
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+    execute_process(
+        COMMAND ${CMAKE_OCAML_OCAMLFIND} ocamlc -where
+        OUTPUT_VARIABLE CMAKE_OCAML_STDLIB_PATH
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+endif()
+
+find_package_handle_standard_args( OCAML "Could NOT find OCaml."
+    CMAKE_OCAML_VERSION
+    CMAKE_OCAML_STDLIB_PATH
+    CMAKE_OCAML_OCAML
+    CMAKE_OCAML_OCAMLFIND
+    )
+        
+mark_as_advanced(
+    CMAKE_OCAML_OCAML
+    CMAKE_OCAML_OCAMLFIND
+    )

CMakeModules/UseOCaml.cmake

+# Macros for OCaml.
+
+# Open issues:
+# - Is it better to connect the generated variables to targets?  Scoping rules
+#   are unknown to me, but I suspect that targets are global, while variables
+#   may not be.
+# - Is it really the case that I need to attach so many properties to the
+#   targets just to be able to navigate them?
+# - It'd be great to be able to list OCaml in the call to project()
+
+# {{{1 set up variables
+set( CMAKE_OCAML_COMPILER ${CMAKE_OCAML_OCAMLFIND} ocamlc
+    CACHE STRING "Command used for bytecode targets."
+    )
+
+set( CMAKE_OCAML_COMPILER_OPT ${CMAKE_OCAML_OCAMLFIND} ocamlopt
+    CACHE STRING "Command used for optimized targets."
+    )
+
+set( CMAKE_OCAML_DEP ${CMAKE_OCAML_OCAMLFIND} ocamldep -modules
+    CACHE STRING "Command used to generate dependencies."
+    )
+
+set( CMAKE_OCAML_QUERY ${CMAKE_OCAML_OCAMLFIND} query
+    CACHE STRING "Command used to find OCaml libraries."
+    )
+
+set( CMAKE_OCAML_PKGINSTALLDIR "lib/ocaml/site-lib"
+    CACHE STRING "Default location for package install."
+    )
+
+mark_as_advanced(
+    CMAKE_OCAML_COMPILER
+    CMAKE_OCAML_COMPILER_OPT
+    CMAKE_OCAML_DEP
+    CMAKE_OCAML_QUERY
+    )
+
+# {{{1 find_ocaml_package
+# find an OCaml package
+macro( find_ocaml_package pkgname )
+    string( TOUPPER ${pkgname} pkgname_uc )
+
+    # find the package
+    execute_process(
+        COMMAND ${CMAKE_OCAML_QUERY} ${pkgname}
+        OUTPUT_VARIABLE OCAML_${pkgname_uc}_INCLUDE_DIR
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+    execute_process(
+        COMMAND ${CMAKE_OCAML_QUERY} -format "%v" ${pkgname}
+        OUTPUT_VARIABLE OCAML_${pkgname_uc}_VERSION
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+
+    find_package_handle_standard_args( ${pkgname} DEFAULT_MSG
+        OCAML_${pkgname_uc}_VERSION
+        OCAML_${pkgname_uc}_INCLUDE_DIR
+        )
+
+    #export variables for found package
+    set( OCAML_${pkgname_uc}_INCLUDE_DIR ${OCAML_${pkgname_uc}_INCLUDE_DIR}
+        CACHE PATH ""
+        )
+    set( OCAML_${pkgname_uc}_LIBRARY_DIR ${OCAML_${pkgname_uc}_INCLUDE_DIR}
+        CACHE PATH ""
+        )
+    mark_as_advanced(
+        OCAML_${pkgname_uc}_INCLUDE_DIR
+        OCAML_${pkgname_uc}_LIBRARY_DIR
+        )
+endmacro()
+
+# {{{1 ocaml_trace
+macro( ocaml_trace msg lst )
+    message( STATUS "${msg}" )
+    if( lst )
+        foreach( i ${lst} )
+            message( STATUS "   ${i}" )
+        endforeach()
+    endif()
+endmacro()
+
+# {{{1 ocaml_parse_arguments
+# parse macro arguments
+# copied from http://www.cmake.org/Wiki/CMakeMacroParseArguments
+macro( ocaml_parse_arguments prefix arg_names option_names )
+    set( default_args )
+    foreach( arg_name ${arg_names} )
+        set( ${prefix}_${arg_name} )
+    endforeach( arg_name )
+    foreach( option ${option_names} )
+        set( ${prefix}_${option} FALSE )
+    endforeach( option )
+
+    set( current_arg_name DEFAULT_ARGS )
+    set( current_arg_list )
+    foreach( arg ${ARGN} )            
+        set( larg_names ${arg_names} )    
+        list( FIND larg_names "${arg}" is_arg_name )                   
+        if( is_arg_name GREATER -1 )
+            set( ${prefix}_${current_arg_name} ${current_arg_list} )
+            set( current_arg_name ${arg} )
+            set( current_arg_list )
+        else( is_arg_name GREATER -1 )
+            set( loption_names ${option_names} )    
+            list( FIND loption_names "${arg}" is_option )            
+            if( is_option GREATER -1 )
+                set( ${prefix}_${arg} TRUE )
+            else( is_option GREATER -1 )
+                set( current_arg_list ${current_arg_list} ${arg} )
+            endif()
+        endif()
+    endforeach()
+    set( ${prefix}_${current_arg_name} ${current_arg_list} )
+endmacro()
+
+# {{{1 ocaml_set_target_deplibs
+# collect dependencies on libraries which are targets
+macro( ocaml_set_target_deplibs target )
+    # collect the libs which are targets
+    unset( OCAML_${target}_TARGET_DEPLIBS )
+    foreach( lib ${OCAML_${target}_LIBRARIES} )
+        list( APPEND OCAML_${target}_TARGET_DEPLIBS ocaml.${lib} )
+    endforeach()
+endmacro()
+
+# {{{1 ocaml_set_target_translibs
+macro( ocaml_set_target_translibs target )
+    set( OCAML_${target}_TARGET_TRANSLIBS ${OCAML_${target}_TARGET_DEPLIBS} )
+    foreach( lib ${OCAML_${target}_LIBRARIES} )
+        get_target_property( translibs ocaml.${lib} TARGET_TRANSLIBS )
+        list( APPEND OCAML_${target}_TARGET_TRANSLIBS ${translibs} )
+    endforeach()
+    if( OCAML_${target}_TARGET_TRANSLIBS )
+        list( REMOVE_DUPLICATES OCAML_${target}_TARGET_TRANSLIBS )
+    endif()
+endmacro()
+
+# {{{1 ocaml_set_target_transpkgs
+macro( ocaml_set_target_transpkgs target )
+    set( OCAML_${target}_TARGET_TRANSPKGS ${OCAML_${target}_PACKAGES} )
+    foreach( lib ${OCAML_${target}_LIBRARIES} )
+        get_target_property( transpkgs ocaml.${lib} TARGET_TRANSPKGS )
+        list( APPEND OCAML_${target}_TARGET_TRANSPKGS ${transpkgs} )
+    endforeach()
+    if( OCAML_${target}_TARGET_TRANSPKGS )
+        list( REMOVE_DUPLICATES OCAML_${target}_TARGET_TRANSPKGS )
+    endif()
+endmacro()
+
+# {{{1 ocaml_set_include_dirs
+# set up include dirs for the target based on the target libs it depends on
+macro( ocaml_set_include_dirs target )
+    # base value is the target's own build output dir
+    set( OCAML_${target}_INCLUDE_DIRS
+        "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir"
+        )
+    foreach( ltarget ${OCAML_${target}_TARGET_DEPLIBS} )
+        get_target_property( obj_dir ${ltarget} OBJECT_DIRECTORY )
+        list( APPEND OCAML_${target}_INCLUDE_DIRS ${obj_dir} )
+    endforeach()
+    get_directory_property( include_dirs INCLUDE_DIRECTORIES )
+    list( APPEND OCAML_${target}_INCLUDE_DIRS ${include_dirs} )
+    list( REMOVE_DUPLICATES OCAML_${target}_INCLUDE_DIRS )
+endmacro()
+
+# {{{1 ocaml_set_link_dirs
+# set up link dirs for the target based on the target libs it depends on
+macro( ocaml_set_link_dirs target )
+    # base value is the target's own build output dir
+    set( OCAML_${target}_LINK_DIRS
+        "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir"
+        )
+    foreach( ltarget ${OCAML_${target}_TARGET_DEPLIBS} )
+        get_target_property( obj_dir ${ltarget} OBJECT_DIRECTORY )
+        list( APPEND OCAML_${target}_LINK_DIRS ${obj_dir} )
+    endforeach()
+    get_directory_property( link_dirs LINK_DIRECTORIES )
+    list( APPEND OCAML_${target}_LINK_DIRS ${link_dirs} )
+    list( REMOVE_DUPLICATES OCAML_${target}_LINK_DIRS )
+endmacro()
+
+# {{{1 ocaml_get_srcs_lex
+macro( ocaml_get_srcs_lex target srcfile srclist )
+    get_filename_component( srcfile_we ${srcfile} NAME_WE )
+    file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir )
+    execute_process(
+        COMMAND ocamllex ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile}
+            -o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.ml
+        OUTPUT_QUIET
+        )
+    list( APPEND ${srclist} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.ml )
+endmacro()
+
+# {{{1 ocaml_get_srcs_yacc
+macro( ocaml_get_srcs_yacc target srcfile srclist )
+    get_filename_component( srcfile_we ${srcfile} NAME_WE )
+    file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir )
+    execute_process(
+        COMMAND ocamlyacc ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile}
+        COMMAND mv
+            ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile_we}.mli
+            ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.mli
+        COMMAND mv
+            ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile_we}.ml
+            ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.ml
+        OUTPUT_QUIET
+        )
+    list( APPEND ${srclist}
+        ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.mli
+        ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcfile_we}.ml
+        )
+endmacro()
+
+# {{{1 ocaml_set_real_srcs
+# collect real source files
+macro( ocaml_set_real_srcs target )
+    unset( OCAML_${target}_REAL_SRCS )
+
+    foreach( src ${OCAML_${target}_SOURCES} )
+        unset( srcfiles )
+
+        get_filename_component( ext ${src} EXT )
+        if( ext STREQUAL ".ml" ) # entry is an implementation
+            list( APPEND srcfiles ${CMAKE_CURRENT_SOURCE_DIR}/${src} )
+        elseif( ext STREQUAL ".mli" ) # entry is an interface
+            list( APPEND srcfiles ${CMAKE_CURRENT_SOURCE_DIR}/${src} )
+        elseif( ext STREQUAL ".mll" ) # entry is a lex file
+            ocaml_get_srcs_lex( ${target} ${src} srcfiles )
+        elseif( ext STREQUAL ".mly" ) # entry is a yacc file
+            ocaml_get_srcs_yacc( ${target} ${src} srcfiles )
+        else() # entry is neither, look in file system
+            if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${src}.ml" )
+                list( APPEND srcfiles "${CMAKE_CURRENT_SOURCE_DIR}/${src}.ml")
+            endif()
+            if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${src}.mli" )
+                list( APPEND srcfiles "${CMAKE_CURRENT_SOURCE_DIR}/${src}.mli")
+            endif()
+            if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${src}.mll" )
+                ocaml_get_srcs_lex( ${target} ${src}.mll srcfiles )
+            endif()
+            if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${src}.mly" )
+                ocaml_get_srcs_yacc( ${target} ${src}.mly srcfiles )
+            endif()
+            if( NOT srcfiles )
+                message( SEND_ERROR "Can't find source files for ${src} (${target}).")
+            endif()
+        endif()
+
+        foreach( src0 ${srcfiles} )
+            if( IS_ABSOLUTE ${src0} )
+                list( APPEND OCAML_${target}_REAL_SRCS ${src0} )
+            else()
+                list( APPEND OCAML_${target}_REAL_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/${src0}" )
+            endif()
+        endforeach()
+    endforeach()
+endmacro()
+
+# {{{1 ocaml_get_dependencies
+macro( ocaml_get_dependencies target srcfile dependencies )
+    unset( ${dependencies} )
+
+    # get som useful variables set up {{{2
+    get_filename_component( srcpath ${srcfile} PATH )
+    get_filename_component( srcname ${srcfile} NAME )
+    get_filename_component( srcname_we ${srcfile} NAME_WE )
+    get_filename_component( srcext ${srcfile} EXT )
+
+    set( is_impl TRUE )
+    set( dep_arg "-impl" )
+    set( has_intf FALSE )
+    if( srcext STREQUAL ".mli" )
+        set( is_impl FALSE )
+        set( dep_arg "-intf" )
+    endif()
+    if( is_impl AND EXISTS "${srcpath}/${srcname_we}.mli" )
+        set( has_intf TRUE )
+    endif()
+    #message( STATUS " * Dependencies for ${srcfile}" )
+    #message( STATUS "   ${srcfile} is_impl: ${is_impl}" )
+    #message( STATUS "   ${srcfile} has_intf: ${has_intf}" )
+    #message( STATUS "   ${srcfile} dep_arg: ${dep_arg}" )
+
+    # get dependencies {{{2
+    execute_process(
+        COMMAND ${CMAKE_OCAML_DEP}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_PF_${srcname}_OCAMLOPTS}
+            ${dep_arg} ${srcfile}
+
+        COMMAND cut -d ":" -f 2-
+
+        COMMAND sed -e "s/^ *//g;s/ *$//g"
+
+        COMMAND tr " " ";"
+
+        OUTPUT_VARIABLE dep_mods
+        RESULT_VARIABLE res
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+    #message( STATUS "   ${srcfile} dep_mods: ${dep_mods}" )
+
+    # for each dependency, look for the real file {{{2
+    foreach( dep_mod ${dep_mods} )
+        unset( location )
+        set( dep_has_intf FALSE )
+
+        # convert the first character in the module name to lowercase, to allow
+        # comparison with source filename
+        execute_process(
+            COMMAND echo ${dep_mod}
+            COMMAND sed -e "s/\\([A-Z]\\)\\(.*\\)/\\l\\1\\2/"
+            OUTPUT_VARIABLE dep_fn
+            OUTPUT_STRIP_TRAILING_WHITESPACE
+            )
+
+        # look among the current target's sources {{{3
+        # iterate over the reported sources rather then the list of real
+        # sources
+        foreach( tgtsrc ${OCAML_${target}_SOURCES} )
+            get_filename_component( tgtsrcname ${tgtsrc} NAME_WE ) # drop extension in case
+            if( dep_fn STREQUAL ${tgtsrcname} )
+                #message( STATUS "   Found ${tgtsrcname} among my own sources." )
+                set( location "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir" )
+                if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${tgtsrcname}.mli" )
+                    set( dep_has_intf TRUE )
+                endif()
+                break()
+            endif()
+        endforeach()
+
+        # look among the target's dependencies {{{3
+        if( NOT location )
+            foreach( tgtdep ${OCAML_${target}_TARGET_DEPLIBS} )
+                get_target_property( srcs ${tgtdep} REAL_SRCS )
+                foreach( depsrc ${srcs} )
+                    get_filename_component( depsrcname ${depsrc} NAME_WE ) # drop extension in case
+                    if( dep_fn STREQUAL ${depsrcname} )
+                        #message( STATUS "   Found ${depsrcname} among the sources of ${tgtdep}." )
+                        get_target_property( tgtdir ${tgtdep} OBJECT_DIRECTORY )
+                        set( location "${tgtdir}" )
+                        # modify dep_has_intf
+                        get_target_property( depsrcdir ${tgtdep} SOURCE_DIRECTORY )
+                        if( EXISTS "${depsrcdir}/${depsrcname}.mli" )
+                            set( dep_has_intf TRUE )
+                        endif()
+                        break()
+                    endif()
+                endforeach()
+            endforeach()
+        endif()
+
+        # look among the target's include dirs {{{3
+        if( NOT location )
+            foreach( idir ${OCAML_${target}_INCLUDE_DIRS} )
+                if( EXISTS "${idir}/${dep_fn}.cmi" ) # check for .cmx too?
+                    set( location ${idir} )
+                    set( dep_has_intf TRUE )
+                elseif( EXISTS "${idir}/${dep_fn}.cmo" ) # check for .cmx too?
+                    set( location ${idir} )
+                endif()
+            endforeach()
+        endif()
+
+        # add the dependency based on the findings {{{3
+        if( location )
+            #message( STATUS "Should add the dependencies for ${dep} in ${location} (intf: ${dep_has_intf})" )
+            if( dep_has_intf )
+                list( APPEND ${dependencies}
+                    "${location}/${dep_fn}.cmi"
+                    )
+            else()
+                list( APPEND ${dependencies}
+                    "${location}/${dep_fn}.cmo"
+                    "${location}/${dep_fn}.cmx"
+                    )
+            endif()
+        else()
+            #message( STATUS "Can't find the location of the dependency '${dep}' for '${target}' (${srcfile})" )
+        endif()
+    endforeach()
+
+    # add a dependency on the sourcefile's .cmi, if there's a .mli file {{{2
+    if( is_impl AND has_intf )
+        list( APPEND ${dependencies} "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${srcname_we}.cmi" )
+    endif()
+
+endmacro()
+
+
+# {{{1 ocaml_add_impl_obj
+# adds targets for an OCaml source file, compiling it to both native and
+# bytecode
+macro( ocaml_add_impl_obj target srcfile )
+    get_filename_component( path ${srcfile} PATH )
+    get_filename_component( name ${srcfile} NAME )
+    get_filename_component( name_we ${srcfile} NAME_WE )
+    get_filename_component( ext ${srcfile} EXT )
+
+    set( cmo_name "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.cmo" )
+    set( cmx_name "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.cmx" )
+    set( obj_name "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.o" )
+    set( annot_name "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.annot" )
+    set( cmi_name "" )
+    file( RELATIVE_PATH annot_rel ${CMAKE_CURRENT_SOURCE_DIR} ${annot_name} )
+
+    # set up list of outputs
+    set( output ${cmo_name} ${cmx_name} ${obj_name} )
+    if( NOT EXISTS "${path}/${name_we}.mli" )
+        set( cmi_name "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.cmi" )
+        list( APPEND output ${cmi_name} )
+    endif()
+    #message( STATUS "   ${srcfile} output: ${output}" )
+
+    # include flags
+    unset( include_flags )
+    foreach( idir ${OCAML_${target}_INCLUDE_DIRS} )
+        list( APPEND include_flags -I ${idir} )
+    endforeach()
+    #message( STATUS "   ${srcfile} include_flags: ${include_flags}" )
+
+    # package flags
+    unset( package_flags )
+    foreach( pkg ${OCAML_${target}_TARGET_TRANSPKGS} )
+        list( APPEND package_flags -package ${pkg} )
+    endforeach()
+    #message( STATUS "   ${srcfile} package_flags: ${package_flags}" )
+
+    # calculate dependencies
+    ocaml_get_dependencies( ${target} ${srcfile} depends )
+    #message( STATUS "   ${srcfile} depends: ${depends}" )
+
+    add_custom_command( OUTPUT ${output}
+        COMMAND ${CMAKE_OCAML_COMPILER}
+            ${include_flags}
+            ${package_flags}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLCOPTS}
+            -o ${cmo_name}
+            -c -impl ${srcfile}
+
+        COMMAND ${CMAKE_OCAML_COMPILER_OPT}
+            ${include_flags}
+            ${package_flags}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLCOPTS}
+            -o ${cmo_name}
+            -c -impl ${srcfile}
+
+        COMMAND ${CMAKE_MODULE_PATH}/scripts/maybe_link ${annot_name} ${annot_rel} ${CMAKE_CURRENT_SOURCE_DIR}
+
+        MAIN_DEPENDENCY ${srcfile}
+        DEPENDS ${depends}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml implementation ${name_we}"
+        )
+    add_custom_target( ${target}.${name_we}.impl
+        DEPENDS ${output}
+        )
+    set_target_properties( ${target}.${name_we}.impl PROPERTIES
+        OUTPUT "${output}"
+        KIND "MLIMPL"
+        CMO "${cmo_name}"
+        CMX "${cmx_name}"
+        OBJ "${obj_name}"
+        CMI "${cmi_name}"
+        SOURCE "${srcfile}"
+        )
+    list( APPEND OCAML_${target}_OBJ_TARGETS "${target}.${name_we}.impl" )
+endmacro()
+
+# {{{1 ocaml_add_intf_obj
+macro( ocaml_add_intf_obj target srcfile )
+    get_filename_component( path ${srcfile} PATH )
+    get_filename_component( name ${srcfile} NAME )
+    get_filename_component( name_we ${srcfile} NAME_WE )
+    get_filename_component( ext ${srcfile} EXT )
+
+    set( output "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.cmi" )
+    #message( STATUS "   ${srcfile} output: ${output}" )
+
+    # include flags
+    unset( include_flags )
+    foreach( idir ${OCAML_${target}_INCLUDE_DIRS} )
+        list( APPEND include_flags -I ${idir} )
+    endforeach()
+    #message( STATUS "   ${srcfile} include_flags: ${include_flags}" )
+
+    # package flags
+    unset( package_flags )
+    foreach( pkg ${OCAML_${target}_TARGET_TRANSPKGS} )
+        list( APPEND package_flags -package ${pkg} )
+    endforeach()
+    #message( STATUS "   ${srcfile} package_flags: ${package_flags}" )
+
+    # calculate dependencies
+    ocaml_get_dependencies( ${target} ${srcfile} depends )
+    #message( STATUS "   ${srcfile} depends: ${depends}" )
+
+    add_custom_command( OUTPUT ${output}
+        COMMAND ${CMAKE_OCAML_COMPILER}
+            ${include_flags}
+            ${package_flags}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLOPTS}
+            ${OCAML_${target}_PF_${name}_OCAMLCOPTS}
+            -o ${output}
+            -c -intf ${srcfile}
+
+        MAIN_DEPENDENCY ${srcfile}
+        DEPENDS ${depends}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml interface ${name_we}"
+        )
+    add_custom_target( ${target}.${name_we}.intf
+        DEPENDS ${output}
+        )
+    set_target_properties( ${target}.${name_we}.intf PROPERTIES
+        OUTPUT "${output}"
+        KIND "MLINTF"
+        CMO ""
+        CMX ""
+        OBJ ""
+        CMI "${output}"
+        SOURCE "${srcfile}"
+        )
+    list( APPEND OCAML_${target}_OBJ_TARGETS "${target}.${name_we}.intf" )
+endmacro()
+
+# {{{1 ocaml_add_objs
+macro( ocaml_add_objs target )
+    unset( OCAML_${target}_OBJ_TARGETS )
+    foreach( srcfile ${OCAML_${target}_REAL_SRCS} )
+        get_filename_component( path ${srcfile} PATH )
+        get_filename_component( name_we ${srcfile} NAME_WE )
+        get_filename_component( ext ${srcfile} EXT )
+
+        if( ext STREQUAL ".ml" )
+            ocaml_add_impl_obj( ${target} ${srcfile} )
+        elseif( ext STREQUAL ".mli" )
+            ocaml_add_intf_obj( ${target} ${srcfile} )
+        endif()
+    endforeach()
+endmacro()
+
+# {{{1 ocaml_add_archives
+macro( ocaml_add_archives target )
+    # {{{2 collect the cmo, cmx and obj
+    unset( cmonames )
+    unset( cmxnames )
+    unset( objnames )
+    foreach( tgtobj ${OCAML_${target}_OBJ_TARGETS} )
+        #message( STATUS "   looking up objects for ${tgtobj}" )
+        get_target_property( kind ${tgtobj} KIND )
+        get_target_property( cmo ${tgtobj} CMO )
+        get_target_property( cmx ${tgtobj} CMX )
+        get_target_property( obj ${tgtobj} OBJ )
+        list( APPEND cmonames ${cmo} )
+        list( APPEND cmxnames ${cmx} )
+        if( kind STREQUAL "COBJ" )
+            list( APPEND objnames ${obj} )
+        endif()
+    endforeach()
+    #message( STATUS "   ${target} archive cmos: ${cmonames}" )
+    #message( STATUS "   ${target} archive cmxs: ${cmxnames}" )
+    #message( STATUS "   ${target} archive objs: ${objnames}" )
+
+    # {{{2 set up package flags
+    unset( package_flags )
+    foreach( pkg ${OCAML_${target}_TARGET_TRANSPKGS} )
+        list( APPEND package_flags -package ${pkg} )
+    endforeach()
+
+    unset( clinkflags )
+    unset( carchives )
+    foreach( lib ${OCAML_${target}_TARGET_TRANSLIBS} )
+        get_target_property( kind ${lib} KIND )
+        if( kind STREQUAL "CLIB" )
+            #message( STATUS "   clib: ${lib}" )
+            get_target_property( objdir ${lib} OBJECT_DIRECTORY )
+            list( APPEND clinkflags -ccopt -L${objdir} )
+            get_target_property( clibs ${lib} LINK_TARGETS )
+            get_target_property( carch ${lib} ARCHIVES )
+            list( APPEND carchives ${carch} )
+            foreach( clib ${clibs} )
+                list( APPEND clinkflags -cclib -l${clib} )
+            endforeach()
+        endif()
+    endforeach()
+    #message( STATUS "   clinkflags: ${clinkflags}" )
+    #message( STATUS "   carchives: ${carchives}" )
+
+    # {{{2 cma archive
+    set( cmaoutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}.cma" )
+    add_custom_command( OUTPUT ${cmaoutput}
+        COMMAND ${CMAKE_OCAML_COMPILER}
+            -a -o ${cmaoutput}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${package_flags}
+            ${objnames}
+            ${cmonames}
+            ${clinkflags}
+
+        DEPENDS ${objnames} ${cmonames} ${carchives}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml library archive ${target}.cma"
+        )
+    add_custom_target( ${target}.cma DEPENDS ${cmaoutput} )
+    set_target_properties( ${target}.cma PROPERTIES
+        OUTPUT ${cmaoutput}
+        OBJS "${cmonames}"
+        CMA ${cmaoutput}
+        CMXA ""
+        )
+
+    # {{{2 cmx archive
+    set( cmxoutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}.cmxa" )
+    set( liboutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}.a" )
+    add_custom_command( OUTPUT ${cmxoutput} ${liboutput}
+        COMMAND ${CMAKE_OCAML_COMPILER_OPT}
+            -a -o ${cmxoutput}
+            ${package_flags}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${objnames}
+            ${cmxnames}
+            ${clinkflags}
+
+        DEPENDS ${objnames} ${cmxnames} ${carchives}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml library archive ${target}.cmxa"
+        )
+    add_custom_target( ${target}.cmxa DEPENDS ${cmxoutput} )
+    set_target_properties( ${target}.cmxa PROPERTIES
+        OUTPUT "${cmxoutput};${liboutput}"
+        OBJS "${cmxnames}"
+        CMA ""
+        CMXA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}.cmxa"
+        )
+    add_custom_target( ${target}.a DEPENDS ${liboutput})
+
+    # {{2 .o object file
+    set( objoutput "${CMAKE_CURRENT_BINARY_DIR}/${target}.o")
+    set( aroutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/lib${target}.a")
+    add_custom_command( OUTPUT ${objoutput}
+        COMMAND ${CMAKE_OCAML_COMPILER}
+            -linkpkg -custom -output-obj -o ${objoutput}
+            ${OCAML_${target}_OCAMLOPTS}
+            ${OCAML_${target}_OCAMLCOPTS}
+            ${package_flags}
+            ${objnames}
+            ${cmonames}
+            ${clinkflags}
+
+        DEPENDS ${objnames} ${cmonames} ${carchives}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml library object ${target}.o"
+        )
+    add_custom_target( ${target}.o DEPENDS ${objoutput} )
+    set_target_properties( ${target}.o PROPERTIES
+        OUTPUT "${objoutput}"
+        OBJS "${cmxnames}"
+        CMA ""
+        CMXA ""
+        )
+    add_custom_command(OUTPUT ${aroutput}
+        COMMAND ar cr ${aroutput} ${objoutput}
+        DEPENDS ${objnames} ${cmxnames} ${carchives} ${objoutput}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml library archive lib${target}.a"
+        )
+    add_custom_target( lib${target}.a DEPENDS ${aroutput})
+    set_target_properties( lib${target}.a PROPERTIES
+        OUTPUT "${aroutput}"
+        OBJS "${cmxnames}"
+        CMA ""
+        CMXA ""
+        )
+
+    # {{{2 set target's ARCHIVES
+    set( OCAML_${target}_ARCHIVES ${target}.cma ${target}.cmxa ${target}.a ${target}.o lib${target}.a)
+endmacro()
+
+# {{{1 add_ocaml_library
+macro( add_ocaml_library target )
+    #message( STATUS "add_ocaml_library( ${target} )" )
+
+    ocaml_parse_arguments( OCAML_${target}
+        "SOURCES;LIBRARIES;PACKAGES;OCAMLOPTS;OCAMLCOPTS"
+        ""
+        ${ARGN}
+        )
+    #message( STATUS "   OCAML_${target}_SOURCES:          ${OCAML_${target}_SOURCES}" )
+    #message( STATUS "   OCAML_${target}_LIBRARIES:        ${OCAML_${target}_LIBRARIES}" )
+    #message( STATUS "   OCAML_${target}_PACKAGES:         ${OCAML_${target}_PACKAGES}" )
+    #message( STATUS "   OCAML_${target}_OCAMLOPTS:        ${OCAML_${target}_OCAMLOPTS}" )
+    #message( STATUS "   OCAML_${target}_OCAMLCOPTS:       ${OCAML_${target}_OCAMLCOPTS}" )
+
+    ocaml_set_target_deplibs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_DEPLIBS:   ${OCAML_${target}_TARGET_DEPLIBS}" )
+
+    ocaml_set_target_translibs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_TRANSLIBS: ${OCAML_${target}_TARGET_TRANSLIBS}" )
+
+    ocaml_set_target_transpkgs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_TRANSPKGS: ${OCAML_${target}_TARGET_TRANSPKGS}" )
+
+    ocaml_set_include_dirs( ${target} )
+    #message( STATUS "   OCAML_${target}_INCLUDE_DIRS:     ${OCAML_${target}_INCLUDE_DIRS}" )
+
+    ocaml_set_link_dirs( ${target} )
+    #message( STATUS "   OCAML_${target}_LINK_DIRS:        ${OCAML_${target}_LINK_DIRS}" )
+
+    # find the real sources for the target
+    ocaml_set_real_srcs( ${target} )
+    #message( STATUS "   OCAML_${target}_REAL_SRCS:        ${OCAML_${target}_REAL_SRCS}" )
+
+    # create all the object targets, and collect information needed for the
+    # archives
+    ocaml_add_objs( ${target} )
+    #message( STATUS "   OCAML_${target}_OBJ_TARGETS:      ${OCAML_${target}_OBJ_TARGETS}" )
+
+    # create the target for the archive
+    ocaml_add_archives( ${target} )
+    #message( STATUS "   OCAML_${target}_ARCHIVES:         ${OCAML_${target}_ARCHIVES}" )
+
+    # create the top-level target for this library and add dependencies on each
+    # object target
+    add_custom_target( ocaml.${target} ALL )
+    set_target_properties( ocaml.${target} PROPERTIES
+        SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        OBJECT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir"
+        KIND "LIBRARY"
+        SOURCES "${OCAML_${target}_SOURCES}"
+        LIBRARIES "${OCAML_${target}_LIBRARIES}"
+        PACKAGES "${OCAML_${target}_PACKAGES}"
+        OCAMLCOPTS "${OCAML_${target}_OCAMLCOPTS}"
+        TARGET_DEPLIBS "${OCAML_${target}_TARGET_DEPLIBS}"
+        TARGET_TRANSLIBS "${OCAML_${target}_TARGET_TRANSLIBS}"
+        TARGET_TRANSPKGS "${OCAML_${target}_TARGET_TRANSPKGS}"
+        INCLUDE_DIRS "${OCAML_${target}_INCLUDE_DIRS}"
+        LINK_DIRS "${OCAML_${target}_LINK_DIRS}"
+        REAL_SRCS "${OCAML_${target}_REAL_SRCS}"
+        OBJ_TARGET "${OCAML_${target}_OBJ_TARGETS}"
+        ARCHIVES "${OCAML_${target}_ARCHIVES}"
+        )
+    add_dependencies( ocaml.${target} ${OCAML_${target}_ARCHIVES} )
+endmacro()
+
+# {{{1 ocaml_get_files_from_target
+# macro which collects different files from a top-level target
+macro( ocaml_get_files_from_target target objs outs srcs )
+endmacro()
+
+# {{{1 ocaml_install_library
+macro( ocaml_install_library pkg lib )
+    #message( STATUS "       package: ${pkg}" )
+    #message( STATUS "       library: ${lib}" )
+    get_target_property( obj_target ocaml.${lib} OBJ_TARGET )
+    #message( STATUS "       obj_target: ${obj_target}" )
+    get_target_property( archives ocaml.${lib} ARCHIVES )
+    #message( STATUS "       archives: ${archives}" )
+
+    unset( files )
+    foreach( tgt ${obj_target} )
+        get_target_property( cmi ${tgt} CMI )
+        get_target_property( source ${tgt} SOURCE )
+        #message( STATUS "       ${tgt} cmi: ${cmi}" )
+        #message( STATUS "       ${tgt} source: ${source}" )
+        list( APPEND files ${cmi} ${source} )
+    endforeach()
+    foreach( arch ${archives} )
+        get_target_property( out ${arch} OUTPUT )
+        #message( STATUS "       ${arch} out: ${out}" )
+        list( APPEND files ${out} )
+    endforeach()
+    #message( STATUS "       files: ${files}" )
+    install(
+        FILES ${files}
+        DESTINATION "${OCAML_INSTALL_${pkg}_DESTINATION}"
+        )
+endmacro()
+
+# {{{1 ocaml_install_c_library
+# ToDo: It seems silly to install the C source files, but maybe that should be
+# done since all the ML sources are installed.
+macro( ocaml_install_c_library pkg lib )
+    #message( STATUS "       package: ${pkg}" )
+    #message( STATUS "       library: ${lib}" )
+    get_target_property( archives ocaml.${lib} ARCHIVES )
+    #message( STATUS "       archives: ${archives}" )
+    
+    set( files ${archives} )
+
+    install(
+        FILES ${files}
+        DESTINATION ${OCAML_INSTALL_${pkg}_DESTINATION}
+        )
+endmacro()
+
+# {{{1 install_ocaml_package
+macro( install_ocaml_package pkg )
+    #message( STATUS "install_ocaml_package( ${pkg} )" )
+
+    ocaml_parse_arguments( OCAML_INSTALL_${pkg}
+        "LIBRARIES;DESTINATION;METAFILE"
+        ""
+        ${ARGN}
+        )
+    if( NOT OCAML_INSTALL_${pkg}_DESTINATION )
+        set( OCAML_INSTALL_${pkg}_DESTINATION "${CMAKE_OCAML_PKGINSTALLDIR}/${pkg}" )
+    endif()
+    #message( STATUS "   libraries:   ${OCAML_INSTALL_${pkg}_LIBRARIES}" )
+    #message( STATUS "   destination: ${OCAML_INSTALL_${pkg}_DESTINATION}" )
+    #message( STATUS "   metafile:    ${OCAML_INSTALL_${pkg}_METAFILE}" )
+
+    foreach( lib ${OCAML_INSTALL_${pkg}_LIBRARIES} )
+        get_target_property( kind ocaml.${lib} KIND )
+        if( kind STREQUAL "LIBRARY" )
+            ocaml_install_library( ${pkg} ${lib} )
+        elseif( kind STREQUAL "CLIB" )
+            ocaml_install_c_library( ${pkg} ${lib} )
+        else()
+            #message( SEND_ERROR "Attempting to install non-library ${lib} as a package" )
+        endif()
+    endforeach()
+
+    if( OCAML_INSTALL_${pkg}_METAFILE )
+        install(
+            FILES ${OCAML_INSTALL_${pkg}_METAFILE}
+            DESTINATION ${OCAML_INSTALL_${pkg}_DESTINATION}
+            RENAME "META"
+            )
+    endif()
+endmacro()
+
+# {{{1 ocaml_add_exe
+macro( ocaml_add_exe target )
+    # {{{2 collect the cmo and cmx
+    unset( cmonames )
+    unset( cmxnames )
+    foreach( tgtobj ${OCAML_${target}_OBJ_TARGETS} )
+        #message( STATUS "   looking up objects for ${tgtobj}" )
+        get_target_property( cmo ${tgtobj} CMO )
+        get_target_property( cmx ${tgtobj} CMX )
+        list( APPEND cmonames ${cmo} )
+        list( APPEND cmxnames ${cmx} )
+    endforeach()
+    #message( STATUS "   ${target} archive cmos: ${cmonames}" )
+    #message( STATUS "   ${target} archive cmxs: ${cmxnames}" )
+
+    # {{{2 set up package flags
+    unset( package_flags )
+    foreach( pkg ${OCAML_${target}_TARGET_TRANSPKGS} )
+        list( APPEND package_flags -package ${pkg} )
+    endforeach()
+    #message( STATUS "   ${target} package flags: ${package_flags}" )
+
+    # {{{2 set up include flags
+    unset( include_flags )
+    foreach( idir ${OCAML_${target}_INCLUDE_DIRS} )
+        list( APPEND include_flags -I ${idir} )
+    endforeach()
+    #message( STATUS "   ${target} include_flags: ${include_flags}" )
+
+    # {{{2 collect cma, cmxa and libs
+    unset( cmanames )
+    unset( cmatargets )
+    unset( cmxanames )
+    unset( cmxatargets )
+    unset( clibnames )
+    unset( clibtargets )
+    foreach( deplib ${OCAML_${target}_TARGET_DEPLIBS} )
+        #message( STATUS "   looking up libs for ${deplib}" )
+        get_target_property( archives ${deplib} ARCHIVES )
+        #message( STATUS "   ${deplib} archives: ${archives}" )
+        get_target_property( kind ${deplib} KIND )
+        #message( STATUS "   ${deplib} kind: ${kind}" )
+
+        if( kind STREQUAL "LIBRARY" )
+            foreach( arc ${archives} )
+                get_target_property( cma ${arc} CMA )
+                get_target_property( cmxa ${arc} CMXA )
+                if( cma )
+                    #message( STATUS "   ${arc} cma: ${cma}" )
+                    list( APPEND cmanames ${cma} )
+                    list( APPEND cmatargets ${arc} )
+                endif()
+                if( cmxa )
+                    #message( STATUS "   ${arc} cmxa: ${cmxa}" )
+                    list( APPEND cmxanames ${cmxa} )
+                    list( APPEND cmxatargets ${arc} )
+                endif()
+            endforeach()
+        elseif( kind STREQUAL "CLIB" )
+            list( APPEND libnames ${archives} )
+            list( APPEND libtargets ${deplib} )
+        endif()
+
+    endforeach()
+    #message( STATUS "   cmanames: ${cmanames}" )
+    #message( STATUS "   cmxanames: ${cmxanames}" )
+    #message( STATUS "   libnames: ${libnames}" )
+    #message( STATUS "   cmatargets: ${cmatargets}" )
+    #message( STATUS "   cmxatargets: ${cmxatargets}" )
+    #message( STATUS "   libtargets: ${libtargets}" )
+
+    unset( cclinkflags )
+    foreach( deplib ${OCAML_${target}_TARGET_TRANSLIBS} )
+        get_target_property( kind ${deplib} KIND )
+        #message( STATUS "*** ${deplib} kind: ${kind}" )
+        if( kind STREQUAL "CLIB" )
+            get_target_property( objdir ${deplib} OBJECT_DIRECTORY )
+            #message( STATUS "*** ${deplib} objdir: ${objdir}" )
+            list( APPEND cclinkflags -ccopt -L${objdir} )
+        endif()
+    endforeach()
+    #message( STATUS "   cclinkflags: ${cclinkflags}" )
+
+    # {{{2 bytecode exe
+    set( exeoutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}" )
+    if( OCAML_${target}_RUN_POST_BUILD )
+        add_custom_command( OUTPUT ${exeoutput}
+            COMMAND ${CMAKE_OCAML_COMPILER}
+                -custom
+                -linkpkg
+                -o ${exeoutput}
+                ${OCAML_${target}_OCAMLCOPTS}
+                ${package_flags}
+                ${include_flags}
+                ${cclinkflags}
+                ${cmanames}
+                ${cmonames}
+
+            COMMAND ${exeoutput}
+            
+            DEPENDS ${cmonames} ${cmanames}
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+            COMMENT "Building OCaml executable ${target}"
+            )
+    else()
+        add_custom_command( OUTPUT ${exeoutput}
+            COMMAND ${CMAKE_OCAML_COMPILER}
+                -custom
+                -linkpkg
+                -o ${exeoutput}
+                ${OCAML_${target}_OCAMLCOPTS}
+                ${package_flags}
+                ${include_flags}
+                ${cclinkflags}
+                ${cmanames}
+                ${cmonames}
+            
+            DEPENDS ${cmonames} ${cmanames}
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+            COMMENT "Building OCaml executable ${target}"
+            )
+    endif()
+    add_custom_target( ${target}.exe DEPENDS ${exeoutput} )
+    if( cmatargets )
+        add_dependencies( ${target}.exe ${cmatargets} )
+    endif()
+    set_target_properties( ${target}.exe PROPERTIES
+        OUTPUT ${exeoutput}
+        )
+
+    # {{{2 optimised exe
+    set( optoutput "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${target}_opt" )
+    if( OCAML_${target}_RUN_POST_BUILD )
+        add_custom_command( OUTPUT ${optoutput}
+            COMMAND ${CMAKE_OCAML_COMPILER_OPT}
+                -o ${optoutput}
+                ${OCAML_${target}_OCAMLCOPTS}
+                ${package_flags}
+                ${include_flags}
+                ${cmxanames}
+                -linkpkg
+                ${cmxnames}
+
+            COMMAND ${optoutput}
+
+            DEPENDS ${cmxnames} ${cmxanames}
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+            COMMENT "Building OCaml executable ${target}_opt"
+            )
+    else()
+        add_custom_command( OUTPUT ${optoutput}
+            COMMAND ${CMAKE_OCAML_COMPILER_OPT}
+                -o ${optoutput}
+                ${OCAML_${target}_OCAMLCOPTS}
+                ${package_flags}
+                ${include_flags}
+                ${cmxanames}
+                -linkpkg
+                ${cmxnames}
+
+            DEPENDS ${cmxnames} ${cmxanames}
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+            COMMENT "Building OCaml executable ${target}_opt"
+            )
+    endif()
+    add_custom_target( ${target}.opt DEPENDS ${optoutput} )
+    if( cmxatargets )
+        add_dependencies( ${target}.opt ${cmxatargets} )
+    endif()
+    set_target_properties( ${target}.opt PROPERTIES
+        OUTPUT ${optoutput}
+        )
+
+    # {{{2 set target's EXE
+    set( OCAML_${target}_EXE ${target}.exe ${target}.opt )
+endmacro()
+
+# {{{1 add_ocaml_executable
+macro( add_ocaml_executable target )
+    #message( STATUS "add_ocaml_executable( ${target} )" )
+
+    ocaml_parse_arguments( OCAML_${target}
+        "SOURCES;LIBRARIES;PACKAGES;OCAMLOPTS;OCAMLCOPTS"
+        "RUN_POST_BUILD"
+        ${ARGN}
+        )
+    #message( STATUS "   OCAML_${target}_SOURCES:          ${OCAML_${target}_SOURCES}" )
+    #message( STATUS "   OCAML_${target}_LIBRARIES:        ${OCAML_${target}_LIBRARIES}" )
+    #message( STATUS "   OCAML_${target}_PACKAGES:         ${OCAML_${target}_PACKAGES}" )
+    #message( STATUS "   OCAML_${target}_OCAMLOPTS:        ${OCAML_${target}_OCAMLOPTS}" )
+    #message( STATUS "   OCAML_${target}_OCAMLCOPTS:       ${OCAML_${target}_OCAMLCOPTS}" )
+    #message( STATUS "   OCAML_${target}_RUN_POST_BUILD:   ${OCAML_${target}_RUN_POST_BUILD}" )
+
+    ocaml_set_target_deplibs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_DEPLIBS:   ${OCAML_${target}_TARGET_DEPLIBS}" )
+
+    ocaml_set_target_translibs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_TRANSLIBS: ${OCAML_${target}_TARGET_TRANSLIBS}" )
+
+    ocaml_set_target_transpkgs( ${target} )
+    #message( STATUS "   OCAML_${target}_TARGET_TRANSPKGS: ${OCAML_${target}_TARGET_TRANSPKGS}" )
+
+    ocaml_set_include_dirs( ${target} )
+    #message( STATUS "   OCAML_${target}_INCLUDE_DIRS:     ${OCAML_${target}_INCLUDE_DIRS}" )
+
+    ocaml_set_link_dirs( ${target} )
+    #message( STATUS "   OCAML_${target}_LINK_DIRS:        ${OCAML_${target}_LINK_DIRS}" )
+
+    ocaml_set_real_srcs( ${target} )
+    #message( STATUS "   OCAML_${target}_REAL_SRCS:        ${OCAML_${target}_REAL_SRCS}" )
+
+    ocaml_add_objs( ${target} )
+    #message( STATUS "   OCAML_${target}_OBJ_TARGETS:      ${OCAML_${target}_OBJ_TARGETS}" )
+
+    ocaml_add_exe( ${target} )
+    #message( STATUS "   OCAML_${target}_EXE:              ${OCAML_${target}_EXE}" )
+
+    add_custom_target( ocaml.${target} ALL )
+    set_target_properties( ocaml.${target} PROPERTIES
+        SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        OBJECT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir"
+        KIND "EXECUTABLE"
+        SOURCES "${OCAML_${target}_SOURCES}"
+        LIBRARIES "${OCAML_${target}_LIBRARIES}"
+        PACKAGES "${OCAML_${target}_PACKAGES}"
+        OCAMLCOPTS "${OCAML_${target}_OCAMLCOPTS}"
+        TARGET_DEPLIBS "${OCAML_${target}_TARGET_DEPLIBS}"
+        TARGET_TRANSLIBS "${OCAML_${target}_TARGET_TRANSLIBS}"
+        TARGET_TRANSPKGS "${OCAML_${target}_TARGET_TRANSPKGS}"
+        INCLUDE_DIRS "${OCAML_${target}_INCLUDE_DIRS}"
+        LINK_DIRS "${OCAML_${target}_LINK_DIRS}"
+        REAL_SRCS "${OCAML_${target}_REAL_SRCS}"
+        OBJ_TARGET "${OCAML_${target}_OBJ_TARGETS}"
+        EXE "${OCAML_${target}_EXE}"
+        )
+    add_dependencies( ocaml.${target} ${OCAML_${target}_OBJ_TARGETS} ${OCAML_${target}_EXE} )
+endmacro()
+
+# {{{1 ocaml_add_c_obj
+macro( ocaml_add_c_obj target srcfile )
+    #message( STATUS "ocaml_add_c_obj( ${target} ${srcfile} )" )
+    get_filename_component( path ${srcfile} PATH )
+    get_filename_component( name ${srcfile} NAME )
+    get_filename_component( name_we ${srcfile} NAME_WE )
+    get_filename_component( ext ${srcfile} EXT )
+
+    set( output ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/${name_we}.o )
+    add_custom_command( OUTPUT ${output}
+        COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir
+
+        COMMAND ${CMAKE_OCAML_COMPILER}
+            -ccopt -o${output}
+            -c ${srcfile}
+
+        MAIN_DEPENDENCY ${srcfile}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml C object ${name_we}"
+        )
+    add_custom_target( ${target}.${name_we}.cobj DEPENDS ${output} )
+    set_target_properties( ${target}.${name_we}.cobj PROPERTIES
+        OUTPUT "${output}"
+        KIND "COBJ"
+        CMO ""
+        CMX ""
+        OBJ "${output}"
+        CMI ""
+        SOURCE "${srcfile}"
+        )
+    list( APPEND OCAML_${target}_OBJ_TARGETS "${target}.${name_we}.cobj" )
+endmacro()
+
+# {{{1 add_ocaml_c_library
+# todo:
+#   add support for CCOPTS
+#   add support for linking against C libraries
+#   re-evaluate whether to use ocamlmklib or straight ar
+macro( add_ocaml_c_library target )
+    #message( STATUS "add_ocaml_c_library( ${target} )" )
+
+    ocaml_parse_arguments( OCAML_${target}
+        "SOURCES;CLIBRARIES"
+        ""
+        ${ARGN}
+        )
+    #message( STATUS "   OCAML_${target}_SOURCES:     ${OCAML_${target}_SOURCES}" )
+    #message( STATUS "   OCAML_${target}_CLIBRARIES:  ${OCAML_${target}_CLIBRARIES}" )
+
+    unset( OCAML_${target}_OBJ_TARGETS )
+    foreach( rs ${OCAML_${target}_SOURCES} )
+        ocaml_add_c_obj( ${target} ${CMAKE_CURRENT_SOURCE_DIR}/${rs} )
+    endforeach()
+    #message( STATUS "   OCAML_${target}_OBJ_TARGETS: ${OCAML_${target}_OBJ_TARGETS}" )
+
+    unset( OCAML_${target}_OBJS )
+    foreach( tgt ${OCAML_${target}_OBJ_TARGETS} )
+        get_target_property( obj ${tgt} OBJ )
+        list( APPEND OCAML_${target}_OBJS ${obj} )
+    endforeach()
+    #message( STATUS "   OCAML_${target}_OBJS:        ${OCAML_${target}_OBJS}" )
+
+    #set( output_a ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/lib${target}.a )
+    #set( output_dll ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/dll${target}.so )
+    #set( output "${output_a};${output_dll}" )
+    #add_custom_command( OUTPUT ${output}
+    #    COMMAND ocamlmklib -oc ${target}
+    #        ${OCAML_${target}_OBJS}
+    #    DEPENDS ${OCAML_${target}_OBJS}
+    #    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir
+    #    COMMENT "Building OCaml C lib ${target}"
+    #    )
+    #add_custom_target( ocaml.${target} ALL DEPENDS ${output} )
+    #set_target_properties( ocaml.${target} PROPERTIES
+    #    KIND "CLIB"
+    #    LINK_TARGETS "${target};${OCAML_${target}_CLIBRARIES}"
+    #    SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    #    OBJECT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir
+    #    LIBRARIES ""
+    #    PACKAGES ""
+    #    OCAMLCOPTS ""
+    #    TARGET_DEPLIBS ""
+    #    TARGET_TRANSLIBS ""
+    #    TARGET_TRANSPKGS ""
+    #    INCLUDE_DIRS ""
+    #    LINK_DIRS ""
+    #    REAL_SRCS ""
+    #    OBJ_TARGET "${OCAML_${target}_OBJ_TARGETS}"
+    #    ARCHIVES "${output}"
+    #    )
+
+    set( output_a ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir/lib${target}.a )
+    set( output "${output_a}" )
+    add_custom_command( OUTPUT ${output}
+        COMMAND ar rc ${output}
+            ${OCAML_${target}_OBJS}
+        DEPENDS ${OCAML_${target}_OBJS}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Building OCaml C lib lib${target}.a"
+        )
+    add_custom_target( ocaml.${target} ALL DEPENDS ${output} )
+    set_target_properties( ocaml.${target} PROPERTIES
+        KIND "CLIB"
+        LINK_TARGETS "${target};${OCAML_${target}_CLIBRARIES}"
+        SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        OBJECT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ocaml.${target}.dir
+        LIBRARIES ""
+        PACKAGES ""
+        OCAMLCOPTS ""
+        TARGET_DEPLIBS ""
+        TARGET_TRANSLIBS ""
+        TARGET_TRANSPKGS ""
+        INCLUDE_DIRS ""
+        LINK_DIRS ""
+        REAL_SRCS ""
+        OBJ_TARGET "${OCAML_${target}_OBJ_TARGETS}"
+        ARCHIVES "${output}"
+        )
+endmacro()
+
+# {{{1 install_ocaml_executable
+macro( install_ocaml_executable exe )
+    #message( STATUS "install_ocaml_executable( ${exe} )" )
+
+    ocaml_parse_arguments( OCAML_INSTALL_${exe}
+        "DESTINATION"
+        ""
+        ${ARGN}
+        )
+    if( NOT OCAML_INSTALL_${exe}_DESTINATION )
+        set( OCAML_INSTALL_${exe}_DESTINATION "bin" )
+    endif()
+    #message( STATUS "   destination: ${OCAML_INSTALL_${exe}_DESTINATION}" )
+
+    get_target_property( tgts ocaml.${exe} EXE )
+    #message( STATUS "   tgts: ${tgts}" )
+    unset( progs )
+    foreach( tgt ${tgts} )
+        get_target_property( out ${tgt} OUTPUT )
+        #message( STATUS "   ${tgt} output: ${out}" )
+        list( APPEND progs ${out} )
+    endforeach()
+    install( PROGRAMS ${progs}
+        DESTINATION ${OCAML_INSTALL_${exe}_DESTINATION}
+        )
+endmacro()
+
+# {{{1 add_ocaml_file_options
+macro( add_ocaml_file_options target )
+    #message( STATUS "add_ocaml_file_options( ${target} )" )
+    ocaml_parse_arguments( OCAML_${target}_PF
+        "SOURCES;OCAMLOPTS;OCAMLCOPTS"
+        ""
+        ${ARGN}
+        )
+    message( STATUS "   sources: ${OCAML_${target}_PF_SOURCES}" )
+    message( STATUS "   ocamlopts: ${OCAML_${target}_PF_OCAMLOPTS}" )
+    message( STATUS "   ocamlopts: ${OCAML_${target}_PF_OCAMLCOPTS}" )
+
+    foreach( src ${OCAML_${target}_PF_SOURCES} )
+        set( OCAML_${target}_PF_${src}_OCAMLOPTS ${OCAML_${target}_PF_OCAMLOPTS} )
+        set( OCAML_${target}_PF_${src}_OCAMLCOPTS ${OCAML_${target}_PF_OCAMLCOPTS} )
+        message( STATUS "   ${src} opts: ${OCAML_${target}_PF_${src}_OCAMLOPTS}" )
+        message( STATUS "   ${src} opts: ${OCAML_${target}_PF_${src}_OCAMLCOPTS}" )
+    endforeach()
+endmacro()
+
+# vim: set tw=0 :
-Copyright (c) 2012, Zachary Anderson (zachary.anderson@inf.ethz.ch)
+Copyright (c) 2012, Zachary Anderson (zanderso@acm.org)
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,

Makefile.in

-# Makefile for a Cil tutorial, based on the Deputy Makefiles.
-# Zach Anderson (zachary.anderson@inf.ethz.ch)
-#
-#
-# Please edit Makefile.in, not Makefile!
-
-ifndef ARCHOS
-  ARCHOS = @ARCHOS@
-endif
-
-ifndef BUILD_DOCS
-  BUILD_DOCS = @BUILD_DOCS@
-endif
-
-ifndef BUILD_TUT11
-  BUILD_TUT11 = @BUILD_TUT11@
-endif
-
-ifndef BUILD_TUT15
-	BUILD_TUT15 = @BUILD_TUT15@
-endif
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-libdir = @libdir@
-pkglibdir = $(libdir)/ciltut
-
-SUBDIRS = ciltut-lib
-
-# It is important to build without NATIVECAML first,to generate the 
-# proper dependencies
-all:
-	$(MAKE) ciltut $(SUBDIRS)
-ifndef BYTECODE
-	$(MAKE) ciltut $(SUBDIRS) NATIVECAML=1
-# For some strange reason the bytecode cil library is remade, which triggers
-# a remake of the ciltut.byte.exe, but not the .asm.exe. This means that 
-# we keep using the bytecode version of ciltut. We force the .asm version to 
-# be the most recent one
-	touch obj/$(ARCHOS)/ciltut.asm.exe
-endif
-
-# Look out for outdated Makefile; if it's out of date, this will automatically
-# re-run ./config.status, then re-exec make with the same arguments.
-Makefile: config.status Makefile.in
-	@echo "Rebuilding the Makefile"
-	./$<
-
-config.status: configure
-	./$@ --recheck
-
-configure: configure.ac
-	autoconf
-
-
-#
-# Ciltut executable
-#
-
-OBJDIR       = obj/$(ARCHOS)
-DEPENDDIR    = obj/.depend
-
-SOURCEDIRS   = src
-
-# Add additional modules here. Order matters. If module x depends on module y,
-# then x has to come after y in the list.
-MODULES = tututil ciltutoptions \
-          tut0 tut1 tut2 tut3 tut4 tut5 tut6 tut7 tut8 tut9 tut10 tut11 tut12 tut13 tut14 tut15 main
-
-OCAMLFIND = @OCAMLFIND@
-CILINC = $(shell $(OCAMLFIND) query cil)
-GRAPHINC = $(shell $(OCAMLFIND) query ocamlgraph)
-
-COMPILEFLAGS = -w x -I $(CILINC) -I $(GRAPHINC)
-LINKFLAGS    = -I $(CILINC) -I $(GRAPHINC)
-
-ifeq ($(BUILD_TUT11),true)
-  COMPILEFLAGS += -I +why3
-  LINKFLAGS += -I +why3
-  PREPROC_ARG = -DBUILD_TUT11
-endif
-
-ifeq ($(BUILD_TUT15),true)
-	PREPROC_ARG += -DBUILD_TUT15
-endif
-
-PREPROC = camlp4o pa_macro.cmo $(PREPROC_ARG)
-
-include Makefile.ocaml
-
-PROJECT_EXECUTABLE = $(OBJDIR)/ciltut$(EXE)
-PROJECT_MODULES    = $(MODULES)
-
-PROJECT_CMODULES =
-EXT_PROJ_CMODS =
-
-PROJECT_LIBS       = unix str nums graph
-
-ifeq ($(BUILD_TUT11), true)
-  PROJECT_LIBS += dynlink why3
-endif
-PROJECT_LIBS += cil
-
-# find the cil library
-vpath %.$(CMXA) $(CILINC)
-
-# Make sure that the ciltut files depend on the CIL library
-# Choose just one file on which everybody depends
-$(OBJDIR)/main.$(CMO): $(CILINC)/cil.$(CMXA)
-
-$(PROJECT_EXECUTABLE) : $(PROJECT_MODULES:%=$(OBJDIR)/%.$(CMO)) \
-                        $(PROJECT_CMODULES:%=$(OBJDIR)/%.$(CMC)) \
-                        cil.$(CMXA)
-	@$(NARRATIVE) "Linking $(COMPILETOWHAT) $@ $(LINKMSG)"
-	$(AT)$(CAMLLINK)  -o $@ \
-                    $(PROJECT_LIBS:%=%.$(CMXA)) \
-                    $(EXT_PROJ_MODS:%=%.$(CMO)) \
-                    $(PROJECT_MODULES:%=$(OBJDIR)/%.$(CMO)) \
-                    $(EXT_PROJ_CMODS:%=%.$(OBJ)) \
-                    $(PROJECT_CMODULES:%=$(OBJDIR)/%.$(CMC)) \
-                    $(ENDLINKFLAGS)
-
-ciltut: $(PROJECT_EXECUTABLE) 
-
-#
-# Subdirectories
-#
-
-.PHONY: $(SUBDIRS)
-
-$(SUBDIRS):
-	$(MAKE) -C $@ -f Makefile.dummy
-
-#
-# Testing and cleanup
-#
-
-clean:
-	rm -rf $(OBJDIR)/*.* $(DEPENDDIR)/*.*
-	for i in $(SUBDIRS); do make -C $$i -f Makefile.dummy clean; done
-
-libclean:
-	for i in ciltut-lib; do make -C $$i -f Makefile.dummy clean; done
-
-distclean: cleancaml clean
-	rm -f config.status config.log Makefile
-	for i in $(SUBDIRS); do make -C $$i -f Makefile.dummy distclean; done
-
-#
-# Installation
-#
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-
-BIN_FILES = bin/ciltutcc \
-            $(OBJDIR)/ciltut.byte.exe \
-            $(OBJDIR)/ciltut.asm.exe
-
-LIB_FILES = lib/Ciltut.pm
-
-INCLUDE_FILES = ciltut-include/ciltut.h
-
-ALL_FILES = $(BIN_FILES) $(LIB_FILES) $(INCLUDE_FILES)
-
-install-base: $(ALL_FILES)
-	$(INSTALL) -d $(DESTDIR)$(prefix)/bin
-	$(INSTALL) -d $(DESTDIR)$(pkglibdir)
-	$(INSTALL) -d $(DESTDIR)$(pkglibdir)/bin
-	$(INSTALL) -d $(DESTDIR)$(pkglibdir)/lib
-	$(INSTALL) -d $(DESTDIR)$(pkglibdir)/include
-	$(INSTALL_PROGRAM) $(BIN_FILES) $(DESTDIR)$(pkglibdir)/bin
-	touch $(DESTDIR)$(pkglibdir)/bin/ciltut.asm.exe
-	$(INSTALL_DATA) $(LIB_FILES) $(DESTDIR)$(pkglibdir)/lib
-	$(INSTALL_DATA) $(INCLUDE_FILES) $(DESTDIR)$(pkglibdir)/include
-	rm -f $(DESTDIR)$(prefix)/bin/ciltutcc
-	ln -s ../lib/ciltut/bin/ciltutcc $(DESTDIR)$(prefix)/bin/ciltutcc
-	for i in $(SUBDIRS); do \
-	  make -C $$i -f Makefile.dummy install; \
-	done
-
-# And now for normal users who want everything installed...
-
-install: install-base
-

Makefile.ocaml

-# -*- Mode: makefile -*-
-# Copyright (c) 2001-2002, 
-#  George C. Necula    <necula@cs.berkeley.edu>
-#  Scott McPeak        <smcpeak@cs.berkeley.edu>
-#  Wes Weimer          <weimer@cs.berkeley.edu>
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# 3. The names of the contributors may not be used to endorse or promote
-# products derived from this software without specific prior written
-# permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  # Generic Makefile for Ocaml projects
-  # Written by necula@cs.berkeley.edu
-  # 
-  # Features: 
-  #   - keeps byproducts of building in a separate directory
-  #   - handles dependencies automatically
-  #   - user specifies just what modules go into a project and 
-  #     everything else is done automatically
-  #   - you can use one Makefile for several Ocaml projects
-  #   
-  # You must include this file in your Makefile. Before the include point 
-  # you must defined the following variables (which are glob al for all Ocaml 
-  # projects specified in one Makefile):
-  # 
-  # CAMLDIR    - the directory where to get the ocaml executables from. 
-  #              Must be empty (defaul) or end with a /
-  # OBJDIR     - the directory where to put all object files. This directory 
-  #              must exist (default obj)
-  # DEPENDDIR  - the directory where to put dependency files. This directory 
-  #              must exist.  (default obj/.depend)
-  # NATIVECAML - if set then will use the native compiler
-  # UNSAFE     - if set then will turn off safety checks (only with NATIVECAML)
-  # CAML_NOOPT - if set then it will not optimizer (default is to optimize when 
-  #              NATIVECAML is used, and not optimize in bytecode mode)
-  # PROFILE    - if set then it will compile and link with "gprof" profiling
-  #              support (NATIVECAML mode only)
-  # ASSEMBLY   - if set then it will keep assembly files
-  # STATIC     - if set then it will compile and link statically
-  #              (NATIVECAML mode only)
-  # PREPROC    - the preprocessor command
-
-  # WIN32      - means that we are using the Windows native tools
-
-  # MODULES    - a list of all modules for all projects defined in the 
-  #              Makefile. Give only the basenames (no directory, 
-  #              no extension).  This is used to create the dependencies.
-  # SOURCEDIRS - a list of all directories containing sources for all 
-  #              projects defined in a Makefile. This is used to set vpath.
-  # MLLS       - a list of all .mll (ocamllex input) files for all 
-  #              projects defined in the Makefile. 
-  # MLYS       - a list of all .mly (ocamlyacc input) files for all 
-  #              projects defined in the Makefile. 
-  # CP4S       - a list of all .p4 (ocamlp4 input) files for all 
-  #              projects defined in the Makefile. 
-  # ECHO       - if specifically set to nothing then it will print 
-  #              all of the commands issued. Set this in the command line
-  #              if you want to see what is going on.
-  #
-  # COMPILEFLAGS      - if defined, then it is passed as argument to ocamlc
-  #                     and ocamlopt
-  # LINKFLAGS         - if defined, then it is passed as argument to 
-  #                     ocamlc and ocamlopt, when linking (at start of 
-  #                     command line)
-  #
-  # CAML_CFLAGS   - flags used only for the compilation of C files.
-  #                 e.g. '-ccopt <gcc flag>'
-  #
-  # BEFOREDEPS  - must list the ML files that must be created before computing 
-  #               dependencies. If you do not do this, then ocamldep will not
-  #               record a dependency on the missing ML files. 
-  #               The files obtained from MLYS and MLLS are 
-  #               handled automatically. This must be set before including this
-  #               Makefile.ocaml
-  # 
-  # After you set all of the above you must do the following for EACH separate 
-  # executable that you want to build.
-  #
-  # Define the following:
-  # PROJECT_EXECUTABLE - the name of the executable you want to build. To take 
-  #                      advantage of the naming scheme that separates the 
-  #                      bytecode version and the native version, use the 
-  #                      $(EXE) variable which is defined to either .byte.exe 
-  #                      or .asm.exe. I typically put the executable in 
-  #                      $(OBJDIR) as well.
-  # PROJECT_MODULES    - the base names of the modules that make this 
-  #                      executable in the order in which they must be
-  #                      passed to the linker. Make sure that all of
-  #                      the names mentioned here are also mentioned in 
-  #                      MODULES.
-  # PROJECT_CMODULES   - same as modules but for the C modules. These
-  #                      do not need to be mentioned in MODULES. There must be
-  #                      no name clashes with MODULES
-  # PROJECT_LIBS       - the base names of the libraries that you 
-  #                      want to link in the executable.
-  #
-  #
-  # After defining these variables, put the following code in your
-  # Makefile to generate a customized rule for making your executable:
-  #
-  # $(PROJECT_EXECUTABLE) : $(PROJECT_MODULES:%=$(OBJDIR)/%.$(CMO)) \
-  #                        $(PROJECT_CMODULES:%=$(OBJDIR)/%.$(CMC))
-  #	@$(NARRATIVE) "Linking $(COMPILETOWHAT) $@ $(LINKMSG)"
-  #	$(AT)$(CAMLLINK) -verbose -o $@ \
-  #                    $(PROJECT_LIBS:%=%.$(CMXA)) \
-  #                    $^
-  #
-  #
-  # Example:
-  # 
-  # OBJDIR     = obj
-  # DEPENDDIR  = obj/.depend
-  # SOURCEDIRS = src src/special
-  # MLLS       = mylex 
-  # MLYS       = myparse
-  #
-  # MODULES    = mod11 mod12 mod21 modcommon
-  #
-  #  # Rules for project 1
-  # PROJECT_EXECUTABLE = $(OBJDIR)/proj1$(EXE)
-  # PROJECT_MODULES    = mod11 mod12 modcommon
-  # PROJECT_CMODULES   =  
-  # PROJEC_LIBS        = unix
-  #  #Standard boilerplate for the executable
-  # $(PROJECT_EXECUTABLE) : $(PROJECT_MODULES:%=$(OBJDIR)/%.$(CMO)) \
-  #                        $(PROJECT_CMODULES:%=$(OBJDIR)/%.$(CMC))
-  #	@$(NARRATIVE) "Linking $(COMPILETOWHAT) $@ $(LINKMSG)"
-  #	$(AT)$(CAMLLINK) -verbose -o $@ \
-  #                    $(PROJECT_LIBS:%=%.$(CMXA)) \
-  #                    $^
-  #
-  #
-  #  # Rules for project 2 
-  # PROJECT_EXECUTABLE = $(OBJDIR)/proj2$(EXE)
-  # PROJECT_MODULES    = mod21 modcommon
-  # PROJECT_CMODULES   =  
-  # PROJEC_LIBS        = unix str
-  #  #Standard boilerplate for the executable
-  # $(PROJECT_EXECUTABLE) : $(PROJECT_MODULES:%=$(OBJDIR)/%.$(CMO)) \
-  #                        $(PROJECT_CMODULES:%=$(OBJDIR)/%.$(CMC))
-  #	@$(NARRATIVE) "Linking $(COMPILETOWHAT) $@ $(LINKMSG)"
-  #	$(AT)$(CAMLLINK) -verbose -o $@ \
-  #                    $(PROJECT_LIBS:%=%.$(CMXA)) \
-  #                    $^
-  #
-
-
-CAMLLEX = ocamllex
-CAMLYACC= ocamlyacc -v
-CAMLDEP = ocamldep
-CAMLP4 = camlp4 pa_o.cmo pa_op.cmo pr_o.cmo
-
-# Internal versions of COMPILEFLAGS and LINKFLAGS.  We'll add additional flags
-# to these.
-COMPILE_FLAGS := $(COMPILEFLAGS)
-LINK_FLAGS    := $(LINKFLAGS)
-
-COMPILE_FLAGS += -I $(OBJDIR)
-
-# sm: two styles for echoing compilation progress:
-#   style 1, by George:
-#     - print English descriptions of what's happening
-#     - set ECHO to "" to see *everything*
-#   style 2, by Scott:
-#     - do not print English descriptions
-#     - print every shell command that is executed which has a side effect,
-#       so that they could be pasted into a shell to reproduce manually
-#     - omit some of the details of dependency generation
-#
-# to be able to choose which style, several variables are used:
-#   @$(NARRATIVE)  - put this before English descriptions for style 1
-#   @$(COMMAND)    - put this before shell commands which are to be
-#                    printed for style 2; the command is *not* executed
-#   $(AT)          - put this before shell commands which are to be executed,
-#                    and also printed in style 2
-#   $(ECHO)        - use in place of '@' for things not printed in either style
-ifdef ECHOSTYLE_SCOTT
-  # 'true' silently consumes its arguments, whereas 'echo' prints them
-  NARRATIVE   := true           
-  COMMAND     := echo
-  AT          := 
-  ECHO        := @
-else
-  NARRATIVE   := echo
-  COMMAND     := true
-  # change these next two definitions to <empty> to echo everything,
-  # or leave as @ to suppress echoing
-  AT          := @
-  ECHO        := @
-endif
-
-ifdef PREPROC
-  COMPILE_FLAGS  += -pp "$(PREPROC)"
-  DEPFLAGS += -pp "$(PREPROC)"
-endif
-
-COMPILEMSG=
-LINKMSG=
-
-ifdef WIN32
-OBJ             = obj
-else
-OBJ             = o
-endif
-EXE		= $(EXEEXT).exe
-
-
-export EXE
-
-
-
-ifdef NATIVECAML
- ifdef PROFILE
-   COMPILE_FLAGS  += -p
-   LINK_FLAGS     += -p
-   COMPILEMSG     += (profile)
-   LINKMSG        += (profile)
- endif
- ifdef ASSEMBLY
-   COMPILE_FLAGS  += -S
- endif
- ifdef STATIC
-   ifdef FLEXLINK
-     COMPILE_FLAGS  += -ccopt "-link -static"
-     LINK_FLAGS     += -ccopt "-link -static"
-   else
-     COMPILE_FLAGS  += -ccopt -static
-     LINK_FLAGS     += -ccopt -static
-   endif
- endif
- #foo := $(shell echo "I am in NATIVECAML mode" >&2; echo whatever)
- CAMLC          = $(CAMLDIR)ocamlopt  $(COMPILE_FLAGS)
- CAMLLINK       = $(CAMLDIR)ocamlopt  $(LINK_FLAGS)
- CMO            = cmx
- CMC            = opt.$(OBJ)  # compiled (and optimized) C
- CMXA           = cmxa
- EXEEXT         = .asm
- MOVEAFTERCAMLC = cmi cmx $(OBJ)
- COMPILETOWHAT  = native code
- # sm: by adding -native in native mode, we prevent spurious
- # dependencies on .cmo files which were causing lots of
- # extra recompilation
- CAMLDEP        = $(CAMLDIR)ocamldep -native
- # CAML_NOOPT maintains its value on entry (default, missing)
-else 
- # Bytecode mode
- CMO            = cmo
- CMXA           = cma
- CMC            = $(OBJ)
- EXEEXT         = .byte
- MOVEAFTERCAMLC = cmi cmo
- COMPILETOWHAT  = bytecode
- ifdef PROFILE
-   CAMLC          = $(CAMLDIR)ocamlcp -p a $(COMPILE_FLAGS)
-   CAMLLINK       = $(CAMLDIR)ocamlcp -p a -custom  $(LINK_FLAGS)
- else
-   CAMLC          = $(CAMLDIR)ocamlc $(COMPILE_FLAGS)
-   CAMLLINK       = $(CAMLDIR)ocamlc -custom  $(LINK_FLAGS)
- endif
- CAML_NOOPT     = 1
-endif
-
-
-ifdef UNSAFE 
- CAMLC          := $(CAMLC) -unsafe -noassert
-endif
-
-ifdef CAML_NOOPT
- ifdef WIN32
-   COMPILE_FLAGS    += -ccopt /Zi -ccopt /Od
-   LINK_FLAGS       += -ccopt /Zi -ccopt /Od
- else
-   ifdef FLEXLINK
-     COMPILE_FLAGS    += -g -ccopt "-link -g"
-   else
-     COMPILE_FLAGS    += -g -ccopt -g
-   endif
-   ifdef MINGW
-     LINK_FLAGS       += -g
-   else
-     ifdef FLEXLINK
-       LINK_FLAGS    += -g -ccopt "-link -g"
-     else
-       LINK_FLAGS    += -g -ccopt -g
-     endif
-   endif
- endif
-else
-  ifdef WIN32
-    COMPILE_FLAGS   += -ccopt /Ox
-  else
-    COMPILE_FLAGS   += -ccopt -O3
-  endif
-endif
-
-
-
-    # Allow searching for .ml and .mli
-vpath %.mll $(SOURCEDIRS)
-vpath %.mly $(SOURCEDIRS)
-vpath %.ml  $(SOURCEDIRS) $(OBJDIR)
-vpath %.mli $(SOURCEDIRS) $(OBJDIR)
-vpath %.c   $(SOURCEDIRS)
-vpath %.p4  $(SOURCEDIRS)
-
-
-
-#  Secondaries are intermediates that we don't want make to delete
-#  By giving the right names to secondary files we tell make where to make
-#  them if they are not already made. VERY USEFUL!!
-
-MLL_LYS:= $(MLLS:%.mll=$(OBJDIR)/%.ml)  \
-          $(MLYS:%.mly=$(OBJDIR)/%.ml) $(MLYS:%.mly=$(OBJDIR)/%.mli) \
-          $(CP4S:%.p4=$(OBJDIR)/%.ml)
-
-.SECONDARY : $(MLL_LYS)
-
-             # Run the lexer generator
-             # Move the result to the OBJDIR directory
-             # If there is a .mli file in the same directory with .mll then
-             # copy it to OBJDIR (where the .ml) file will live.
-$(OBJDIR)/%.ml: %.mll
-	$(CAMLLEX) $<
-	$(AT)mv -f $(basename $<).ml $(OBJDIR)/
-	$(ECHO)if test -f $(basename $<).mli ;then \
-	  $(COMMAND) cp -f $(basename $<).mli $(OBJDIR)/; \
-	  cp -f $(basename $<).mli $(OBJDIR)/ \
-        ;fi
-
-             # Run the parser generator
-             # Move the result to the $(OBJDIR) directory.
-$(OBJDIR)/%.ml $(OBJDIR)/%.mli: %.mly
-	$(CAMLYACC) $(CAMLYACCFLAGS) $<
-	$(AT)mv -f $(basename $<).ml $(basename $<).mli $(OBJDIR)/
-
-$(OBJDIR)/%.ml: %.p4
-	$(CAMLP4) -impl $< > $@
-	$(ECHO)if test -f $(basename $<).mli ;then \
-		$(COMMAND) cp -f $(basename $<).mli $(OBJDIR); \
-		cp -f $(basename $<).mli $(OBJDIR) \
-       ;fi
-
-           # Compile an MLI file. After compilation move the result to OBJDIR
-$(OBJDIR)/%.cmi: %.mli
-	@$(NARRATIVE) Compiling interface $<
-	$(AT)$(CAMLC) -c $<
-	$(ECHO)if test $(OBJDIR) != $(<D) ;then \
-                   $(COMMAND) mv -f $(basename $<).cmi $(OBJDIR)/; \
-                   mv -f $(basename $<).cmi $(OBJDIR)/ \
-        ;fi
-
-         # Compile an ML file. After compilation we 
-         # copy to $(OBJDIR) the .cmi and the result of compilation.
-$(OBJDIR)/%.$(CMO): %.ml
-	@$(NARRATIVE) "Compiling           $< to $(COMPILETOWHAT) $(COMPILEMSG)"
-#	$(ECHO)#if test $(OBJDIR) != $(<D) -a -f $(OBJDIR)/$(basename $(<F)).cmi ;then \
-#           $(COMMAND) mv -f $(OBJDIR)/$(basename $(<F)).cmi $(<D); \
-#           mv -f $(OBJDIR)/$(basename $(<F)).cmi $(<D); \
-#        fi
-	@$(COMMAND) $(CAMLC) -c $<
-	$(ECHO)$(CAMLC) -c $< ; res=$$?; \
-	   if test $(OBJDIR) != $(<D) ;then \
-              for ext in $(MOVEAFTERCAMLC); do \
-                if test -f $(basename $<).$$ext ;then \
-                  $(COMMAND) mv -f $(basename $<).$$ext $(OBJDIR)/; \
-                  mv -f $(basename $<).$$ext $(OBJDIR)/; \
-                fi; \
-              done; \
-           fi; exit $$res
-
-             # Compile C files
-             # They appear to be left in the current directory as .o files
-$(OBJDIR)/%.$(CMC): %.c
-	@$(NARRATIVE) "Compiling C file $< $(COMPILEMSG)"
-	$(AT)$(CAMLC) $(CAML_CFLAGS) -c $< -o $@
-	$(AT)mv -f $(basename $(notdir $<)).$(OBJ) $@
-
-              # Special rule for profile.c
-CAMLC_NOPROF=$(subst -p,,$(CAMLC))
-$(OBJDIR)/profile.$(CMC): profile.c
-	@$(NARRATIVE) "Compiling C file $<"
-	$(AT)$(CAMLC_NOPROF) $(CAML_CFLAGS) -c $< -o $@
-	$(AT)mv -f $(basename $(notdir $<)).$(OBJ) $@
-
-
-#	Phonies should be "remade" even if someone mistakenly creates them
-.PHONY: cleancaml
-cleancaml:
-	-rm -f $(OBJDIR)/*.cmi
-	-rm -f $(OBJDIR)/*.cmo
-	-rm -f $(OBJDIR)/*.cmx
-	-rm -f $(OBJDIR)/*.cma
-	-rm -f $(OBJDIR)/*.cmxa
-	-rm -f $(OBJDIR)/*.exe
-	-rm -f $(OBJDIR)/*.obj
-	-rm -f $(OBJDIR)/*.o
-	-rm -f $(OBJDIR)/*.obj
-	-rm -f $(OBJDIR)/*.o
-	-rm -f $(OBJDIR)/*.lib
-	-rm -f $(OBJDIR)/*.a
-	-rm -f $(OBJDIR)/*.mli
-	-rm -f $(OBJDIR)/*.ml
-	-rm -f $(DEPENDDIR)/*.d $(DEPENDDIR)/*.di
-	-rm -f $(MLLS:%.mll=$(OBJDIR)/%.ml) \
-               $(MLLS:%.mll=$(OBJDIR)/%.mli) \
-               $(MLYS:%.mly=$(OBJDIR)/%.ml) \
-               $(MLYS:%.mly=$(OBJDIR)/%.mli) \
-               $(CP4S:%.p4=$(OBJDIR)/%.ml)
-
-
-
-# Before we generate the dependencies, we must make sure to create all the 
-# ML files that we need. Otherwise, the ocamldep will not point out a 
-# dependency to a missing file
-BEFOREDEPS += $(MLLS:%.mll=$(OBJDIR)/%.ml) $(MLYS:%.mly=$(OBJDIR)/%.ml)
-
-# Automatic dependency generation (see GNU info for details)
-#
-# Each .ml file has a .d (dependency file) which is automatically
-# generated and included by the rules below.  The perl script replaces
-# directory paths with $(OBJDIR)/
-#
-# Dependencies for .mli files reside in corresponding .di files.
-#
-
-# Replace the directories in the dependency rules with $(OBJDIR)/, since 
-# we'll move .cmo/.cmx files there.
-# 1. Strip any text followed by / or \.  The / case even strips slashes that
-#    are preceded by whitespace, to account for unix absolute paths.
-#    The \ case does not strip slashes that come immediately after whitespace,
-#    to preserve the trailing \ at the end of Makefile rules.
-# 2. Replace these directory names by '$(OBJDIR)/'
-FIXDEPEND:=perl -e 'while(<>) { s%[^/\\ :]*/% %g; s%[^/\\ :]+\\% %g; s%([-a-zA-Z0-9+-.:/\/_]+)%\$$(OBJDIR)/$$1%g; print $$_;}'
-# FIXDEPEND:=cat
-
-DEPINCLUDES= -I $(OBJDIR) $(SOURCEDIRS:%=-I %)
-$(DEPENDDIR)/%.d: %.ml $(BEFOREDEPS)
-	@$(NARRATIVE) "Generating dependency information for $<"
-	$(ECHO)if ! [ -d $(DEPENDDIR) ]; then mkdir -p $(DEPENDDIR) ; fi
-	@$(COMMAND) $(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) $<
-	$(ECHO)$(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) $< | $(FIXDEPEND) > $@
-
-$(DEPENDDIR)/%.di: %.mli $(BEFOREDEPS)
-	@$(NARRATIVE) "Generating dependency information for $<"
-	$(ECHO)if ! [ -d $(DEPENDDIR) ]; then mkdir -p $(DEPENDDIR) ; fi
-	@$(COMMAND) $(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) $<
-	$(ECHO)$(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) $< | $(FIXDEPEND) > $@