2626# - <library_name>_c the C-bindings with <library_name> linked to it
2727# - <library_name>_fortran the Fortran-bindings with <library_name> linked to it
2828
29- include_guard ()
29+ include_guard (GLOBAL )
3030
3131option (GT_ENABLE_BINDINGS_GENERATION "If turned off, bindings will not be generated." ON )
3232
@@ -35,7 +35,7 @@ set(__CPP_BINDGEN_SOURCE_DIR @__CPP_BINDGEN_SOURCE_DIR@)
3535set (__CPP_BINDGEN_INCLUDE_DIR @__CPP_BINDGEN_INCLUDE_DIR@)
3636
3737add_library (cpp_bindgen_interface INTERFACE )
38- target_include_directories (cpp_bindgen_interface INTERFACE ${__CPP_BINDGEN_INCLUDE_DIR} )
38+ target_include_directories (cpp_bindgen_interface INTERFACE $<BUILD_INTERFACE: $ {__CPP_BINDGEN_INCLUDE_DIR}> $<INSTALL_INTERFACE: include > )
3939target_compile_features (cpp_bindgen_interface INTERFACE cxx_std_11)
4040target_compile_definitions (cpp_bindgen_interface INTERFACE BOOST_PP_VARIADICS=1)
4141if (CPP_BINDGEN_GT_LEGACY)
@@ -65,18 +65,25 @@ function(bindgen_enable_fortran_library target_name)
6565 set (__CPP_BINDGEN_CMAKE_DIR @__CPP_BINDGEN_CMAKE_DIR@)
6666
6767 if (CMAKE_Fortran_COMPILER_LOADED)
68- if (NOT TARGET fortran_bindings_handle)
69- add_library (fortran_bindings_handle ${__CPP_BINDGEN_SOURCE_DIR} /cpp_bindgen/array_descriptor.f90 ${__CPP_BINDGEN_SOURCE_DIR} /cpp_bindgen/handle.f90)
70- target_link_libraries (fortran_bindings_handle PUBLIC cpp_bindgen_handle)
71- target_include_directories (fortran_bindings_handle PUBLIC ${CMAKE_CURRENT_BINARY_DIR} )
72- include (${__CPP_BINDGEN_CMAKE_DIR} /fortran_helpers.cmake)
73- bindgen_enable_fortran_preprocessing_on_target(fortran_bindings_handle)
68+ if (NOT TARGET cpp_bindgen_fortran_handle)
69+ add_library (cpp_bindgen_fortran_handle ${__CPP_BINDGEN_SOURCE_DIR} /cpp_bindgen/array_descriptor.f90 ${__CPP_BINDGEN_SOURCE_DIR} /cpp_bindgen/handle.f90)
70+ # the following variable is used to install the .mod files in install_cpp_bindgen_targets() and
71+ # therefore needs to be available project-wide
72+ set (CPP_BINDGEN_Fortran_MODULES_DIRECTORY ${CMAKE_BINARY_DIR} /cpp_bindgen_modules
73+ CACHE INTERNAL "Directory for Fortran modules of cpp_bindgen" )
74+ set_target_properties (cpp_bindgen_fortran_handle PROPERTIES Fortran_MODULE_DIRECTORY ${CPP_BINDGEN_Fortran_MODULES_DIRECTORY} )
75+ target_link_libraries (cpp_bindgen_fortran_handle PUBLIC cpp_bindgen_handle)
76+ target_include_directories (cpp_bindgen_fortran_handle INTERFACE $<BUILD_INTERFACE:${CPP_BINDGEN_Fortran_MODULES_DIRECTORY} > $<INSTALL_INTERFACE:include />)
77+ include (${__CPP_BINDGEN_CMAKE_DIR} /cpp_bindgen_fortran_helpers.cmake)
78+ bindgen_enable_fortran_preprocessing_on_target(cpp_bindgen_fortran_handle)
7479 endif ()
7580 if (NOT TARGET ${target_name} _fortran)
7681 set_source_files_properties (GT_${${target_name} _fortran_bindings_path} PROPERTIES GENERATED TRUE )
77- add_library (${target_name} _fortran EXCLUDE_FROM_ALL ${GT_ ${target_name} _fortran_bindings_path})
82+ add_library (${target_name} _fortran EXCLUDE_FROM_ALL ${CPP_BINDGEN_ ${target_name} _fortran_bindings_path})
7883 target_link_libraries (${target_name} _fortran PUBLIC ${target_name} )
79- target_link_libraries (${target_name} _fortran PUBLIC fortran_bindings_handle)
84+ target_link_libraries (${target_name} _fortran PUBLIC cpp_bindgen_fortran_handle)
85+ # location of .mod file (we cannot know the INSTALL_INTERFACE directory here)
86+ target_include_directories (${target_name} _fortran PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR} >)
8087 add_dependencies (${target_name} _fortran ${target_name} _declarations)
8188 endif ()
8289 elseif (NOT ${ARGN} ) # internal: the second (optional) parameter can be used to surpress this fatal error
@@ -159,7 +166,41 @@ function(bindgen_add_library target_name)
159166 # bindings Fortran library
160167 # Export the name of the generated file. The variable needs to exist in the whole cmake!
161168 # Reason: see description of bindgen_enable_fortran_library().
162- set (GT_ ${target_name} _fortran_bindings_path ${bindings_fortran_decl_filename}
169+ set (CPP_BINDGEN_ ${target_name} _fortran_bindings_path ${bindings_fortran_decl_filename}
163170 CACHE INTERNAL "Path to the generated Fortran file for ${target_name} " )
164171 bindgen_enable_fortran_library(${target_name} TRUE )
165172endfunction ()
173+
174+ # install_cpp_bindgen_targets()
175+ #
176+ # cpp_bindgen contains some generic files which are being built on first use of bindgen_add_library().
177+ # These libraries can be installed with this function which takes the same arguments
178+ # as install(TARGETS targets... [other-options]), except
179+ # - you must not specify "TARGETS targets..." but only all [other-options].
180+ # - if Fortran is enabled Fortran_MODULE_DESTINATION needs to be set to the location where Fortran modules
181+ # should be installed to (e.g. include)
182+ function (install_cpp_bindgen_targets)
183+ set (options )
184+ set (oneValueArgs Fortran_MODULE_DESTINATION)
185+ set (multiValueArgs TARGETS)
186+ cmake_parse_arguments (ARG "${options} " "${oneValueArgs} " "${multiValueArgs} " ${ARGN} )
187+
188+ if (ARG_TARGETS)
189+ message (FATAL_ERROR "install_cpp_bindgen_targets() must not be called with TARGETS argument." )
190+ endif ()
191+
192+ if (TARGET cpp_bindgen_fortran_handle) # Fortran is enabled, we need to install a mod file
193+ if (ARG_Fortran_MODULE_DESTINATION)
194+ install (DIRECTORY ${CPP_BINDGEN_Fortran_MODULES_DIRECTORY} / DESTINATION ${ARG_Fortran_MODULE_DESTINATION} )
195+ else ()
196+ message (WARNING "Fortran_MODULE_DESTINATION was NOT specified, but Fortran was enabled. Modules files for
197+ cpp_bindgen won't be installed." )
198+ endif ()
199+ install (TARGETS cpp_bindgen_fortran_handle ${ARG_UNPARSED_ARGUMENTS} )
200+ else ()
201+ if (ARG_Fortran_MODULE_DESTINATION)
202+ message (WARNING "Fortran_MODULE_DESTINATION was specified, but Fortran is disabled." )
203+ endif ()
204+ endif ()
205+ install (TARGETS cpp_bindgen_generator cpp_bindgen_handle cpp_bindgen_interface ${ARG_UNPARSED_ARGUMENTS} )
206+ endfunction ()
0 commit comments