fortran_dependencies.mk 3.95 KB
Newer Older
1
# Copyright 2015 Lorenz Hüdepohl
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
2 3 4 5 6
#
# This file is part of fdep and licensed under the MIT license
# see the file LICENSE for more information
#

7 8 9 10
define translate_name
$(subst -,_,$(subst .,_,$1))
endef

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
11 12 13
_f90_verbose = $(_f90_verbose_$(V))
_f90_verbose_ = $(_f90_verbose_$(AM_DEFAULT_VERBOSITY))
_f90_verbose_0 = @echo "  $1";
14 15 16
_f90_only_verbose = $(_f90_only_verbose_$(V))
_f90_only_verbose_ = @
_f90_only_verbose_0 = @
17
_f90_targets = $(call translate_name,$(PROGRAMS) $(LTLIBRARIES))
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
18 19 20 21 22 23 24 25 26

FORTRAN_CPP ?= cpp -P -traditional -Wall -Werror

# $1 source files
#
# returns: file without any .F90 .f90 .F .f extension
define strip_fortran_ext
$(patsubst %.F90,%,$(patsubst %.f90,%,$(patsubst %.F,%,$(patsubst %.f,%,$1))))
endef
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
27 28

# $1 program
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
29 30 31 32 33 34
#
# returns:
#  '1' if object files for target $1 are prefixed due to 'per-target' flags,
#  '' (the empty string) otherwise. See the automake manual for 'per-target'
#  compilation
#
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
35
define is_per_target
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49
$(if $(filter $(call strip_fortran_ext,$(firstword $(call fortran_sources,$1))),$(patsubst %.o,%,$(patsubst %.lo,%,$($1_OBJECTS)))),,1)
endef

# $1 top-level target name (i.e. an entry of _f90_targets)
#
# returns: all target source files matching *.F90 *.f90 *.F *.f
define fortran_sources
$(filter %.F90 %.f90 %.F %.f,$($1_SOURCES))
endef

# $1 top-level target name
#
# returns: the appropriate extension (i.e. 'o' for normal programs, '.lo' for libraries)
define object_extension
50
$(if $(filter $1,$(PROGRAMS)),o,lo)
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
51 52
endef

53 54 55 56 57 58 59 60
# $1 source file
# $2 stem
# $3 program
# $4 kind of file ('use' or 'def')
define modinfo_name
$(dir $1)$(2)$(call strip_fortran_ext,$(notdir $1)).$4_mods_$(patsubst .,_,$3).$(call object_extension,$3)
endef

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
61 62 63 64
# $1 source_file
# $2 stem
# $3 program
define module_targets
65 66 67 68
$(eval _$(3)_use_mods += $(call modinfo_name,$1,$2,$3,use))
$(call modinfo_name,$1,$2,$3,use): $1 $(dir $1)$(am__dirstamp)
	$(call _f90_verbose,F90 USE  [$3] $$<)$(FORTRAN_CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $($p_CPPFLAGS) $(CPPFLAGS) -o /dev/stdout $$< | \
		grep -i -o '^ *use [^ ,!:]*' | sed 's/^[[:space:]]*//;' | tr '[:upper:]' '[:lower:]' | sort -u > $$@
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
69

70 71 72 73
$(eval _$(3)_def_mods += $(call modinfo_name,$1,$2,$3,def))
$(call modinfo_name,$1,$2,$3,def): $1 $(dir $1)$(am__dirstamp)
	$(call _f90_verbose,F90 MOD  [$3] $$<)$(FORTRAN_CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $($p_CPPFLAGS) $(CPPFLAGS) -o /dev/stdout $$< | \
		grep -i -o '^ *module [^!]*' | sed 's/^[[:space:]]*//;' | tr '[:upper:]' '[:lower:]' | grep -v "\<procedure\>\|\<intrinsic\>" > $$@ || true
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
74 75

endef
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
76
$(foreach p,$(_f90_targets),$(if $(call is_per_target,$p),$(foreach s,$(call fortran_sources,$p),$(eval $(call module_targets,$s,$p-,$p))),$(foreach s,$(call fortran_sources,$p),$(eval $(call module_targets,$s,,$p)))))
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
77

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
78 79
_f90_depdir=$(abs_builddir)/.fortran_dependencies
_f90_depfile = $(_f90_depdir)/dependencies.mk
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
80

81 82 83 84 85
# $1 target-name
define recursive_lib_deps
$(foreach l,$(call translate_name,$($1_LDADD) $($1_LIBADD)),$l $(call recursive_lib_deps,$l))
endef

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
86
define is_clean
87
$(if $(filter-out mostlyclean clean distclean maintainer-clean am--depfiles,$(MAKECMDGOALS)),0,1)
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
88 89
endef

90 91 92 93 94
define newline


endef

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
95 96 97
ifneq ($(call is_clean),1)
include $(_f90_depfile)
endif
98 99 100

# $1 program
define program_dependencies
101
	$(_f90_only_verbose){ $(foreach argument,$(_$p_use_mods) $(_$p_def_mods) $(foreach l,$(call recursive_lib_deps,$p),$(_$l_use_mods) $(_$l_def_mods)),echo $(argument); ) true; } | \
102
	$(top_srcdir)/fdep/fortran_dependencies.pl $p >> $@ || { rm $@; exit 1; }
103 104 105

endef

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
106
$(_f90_depfile): $(top_srcdir)/fdep/fortran_dependencies.pl $(foreach p,$(_f90_targets),$(_$p_use_mods) $(_$p_def_mods)) | $(foreach p,$(_f90_targets),$(_f90_depdir)/$p)
107
	$(call _f90_verbose,F90 DEPS $@)echo > $@;
108
	$(foreach p,$(_f90_targets),$(call program_dependencies,$p))
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
109

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
110
$(_f90_depdir):
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
111 112
	@mkdir $@

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
113
$(foreach p,$(_f90_targets),$(_f90_depdir)/$p): | $(_f90_depdir)
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
114 115
	@mkdir $@

Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
116 117
CLEANFILES += $(foreach p,$(_f90_targets),$(_$p_def_mods) $(_$p_use_mods))
CLEANFILES += $(foreach p,$(_f90_targets),$(_f90_depdir)/$p/*)
Lorenz Hüdepohl's avatar
Lorenz Hüdepohl committed
118
CLEANFILES += $(_f90_depfile)