From c7688e901c2fa0c8ede46c4af36ad6be6424c6e8 Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin Date: Mon, 13 May 2024 16:36:06 +0200 Subject: [PATCH] mkhelper.mk.in: an example of two-step Fortran compilation. --- .gitignore | 1 + configure | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 16 +++++++++++ mkhelper.mk.in | 28 +++++++++++++++---- 4 files changed, 115 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index a5aa7fa..b3e48a2 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ Makefile # Build stage files *.a +*.modstamp *.o /main /mod diff --git a/configure b/configure index 4ab253e..64713e8 100755 --- a/configure +++ b/configure @@ -616,6 +616,9 @@ FC_INC_ORDER_PP_f90 FC_INC_FLAG_PP_f90 FC_INC_ORDER FC_INC_FLAG +SEPARATE_MODS_DISABLED +SEPARATE_MODS_ENABLED +FC_MOD_ONLY FC_ROOT_SMOD FC_SMOD_FILE_EXT FC_SMOD_FILE_INFIX @@ -687,6 +690,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_rpaths +enable_separate_mods enable_silent_rules enable_additional_mods enable_openmp @@ -1356,6 +1360,8 @@ Optional Features: --enable-rpaths prepend LDFLAGS with additional linker flags to add directories specified with -L flags to the runtime library search path (RPATH) [default=yes] + --enable-separate-mods enable the two-step compilation of the Fortran + source files [default=yes] --enable-silent-rules less verbose build output (undo: "make V=1") [default=yes] --enable-additional-mods @@ -3599,6 +3605,75 @@ else fi +# Check whether --enable-separate-mods was given. +if test "${enable_separate_mods+set}" = set; then : + enableval=$enable_separate_mods; +else + enable_separate_mods=yes +fi + +if test "x$enable_separate_mods" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran compiler flag needed to generate module files but no object files" >&5 +$as_echo_n "checking for Fortran compiler flag needed to generate module files but no object files... " >&6; } +if ${acx_cv_fc_module_only_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + acx_cv_fc_module_only_flag=unknown + as_dir=conftest.dir; as_fn_mkdir_p + cd conftest.dir + cat > conftest.$ac_ext <<_ACEOF + module conftest_module + end module +_ACEOF + if test "x$acx_cv_fc_module_naming_upper" = xyes; then : + acx_tmp="CONFTEST_MODULE.$acx_cv_fc_module_naming_ext" +else + acx_tmp="conftest_module.$acx_cv_fc_module_naming_ext" +fi + acx_save_FCFLAGS=$FCFLAGS + for acx_flag in '-syntax-only' '-fsyntax-only' '-Msyntax-only' '-otype=mod' '-dB -M2179'; do + FCFLAGS="$acx_save_FCFLAGS $acx_flag" + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -f $acx_tmp && test ! -f conftest.$ac_objext; then : + acx_cv_fc_module_only_flag=$acx_flag; break +else + rm -f $acx_tmp conftest.$ac_objext +fi + done + FCFLAGS=$acx_save_FCFLAGS + cd .. + rm -rf conftest.dir +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_fc_module_only_flag" >&5 +$as_echo "$acx_cv_fc_module_only_flag" >&6; } + if test "x$acx_cv_fc_module_only_flag" = xunknown; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "unable to detect Fortran compiler flag needed to generate module files but no object files +See \`config.log' for more details" "$LINENO" 5; } +else + FC_MOD_ONLY=$acx_cv_fc_module_only_flag +fi + SEPARATE_MODS_ENABLED='' + SEPARATE_MODS_DISABLED='#' +else + FC_MOD_ONLY= + SEPARATE_MODS_ENABLED='#' + SEPARATE_MODS_DISABLED='' +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran compiler flag needed to specify search paths for the \"INCLUDE\" statement" >&5 $as_echo_n "checking for Fortran compiler flag needed to specify search paths for the \"INCLUDE\" statement... " >&6; } if ${acx_cv_fc_ftn_include_flag+:} false; then : diff --git a/configure.ac b/configure.ac index eaea77d..82b833a 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,22 @@ ACX_FC_MODULE_SNAMING( ACX_FC_MODULE_ROOT_SMOD( [AC_SUBST([FC_ROOT_SMOD], [$acx_cv_fc_module_root_smod])]) +AC_ARG_ENABLE([separate-mods], + [AS_HELP_STRING([--enable-separate-mods], + [enable the two-step compilation of the Fortran source files +@<:@default=yes@:>@])], [], + [enable_separate_mods=yes]) +AS_VAR_IF([enable_separate_mods], [yes], + [ACX_FC_MODULE_ONLY_FLAG([FC_MOD_ONLY=$acx_cv_fc_module_only_flag]) + SEPARATE_MODS_ENABLED='' + SEPARATE_MODS_DISABLED='#'], + [FC_MOD_ONLY= + SEPARATE_MODS_ENABLED='#' + SEPARATE_MODS_DISABLED='']) +AC_SUBST([FC_MOD_ONLY]) +AC_SUBST([SEPARATE_MODS_ENABLED]) +AC_SUBST([SEPARATE_MODS_DISABLED]) + ACX_FC_INCLUDE_FLAG( [AC_SUBST([FC_INC_FLAG], [$acx_cv_fc_ftn_include_flag])]) ACX_FC_INCLUDE_ORDER( diff --git a/mkhelper.mk.in b/mkhelper.mk.in index 16e615e..e24bb1d 100644 --- a/mkhelper.mk.in +++ b/mkhelper.mk.in @@ -17,6 +17,7 @@ bundled_subdirs:= \ # Path to the directory with the Fortran module files: moddir:= mod +@SEPARATE_MODS_ENABLED@moddir_null:= $(moddir)/null # Paths to the installation directories: prefix= @prefix@ @@ -36,7 +37,7 @@ SHELL= @SHELL@ # Fortran compiler flags: FCFLAGS= @FCFLAGS@ -makefile_FCFLAGS= @FC_MOD_IN@$(moddir) @FC_MOD_OUT@$(moddir) @FC_INC_FLAG@$(srcdir)/src/include @FC_INC_FLAG_PP_f90@$(srcdir)/src/include @config_FCFLAGS@ @BUNDLED_FCFLAGS@ @NETCDF_FCFLAGS@ +makefile_FCFLAGS= @FC_MOD_IN@$(moddir) @FC_INC_FLAG@$(srcdir)/src/include @FC_INC_FLAG_PP_f90@$(srcdir)/src/include @config_FCFLAGS@ @BUNDLED_FCFLAGS@ @NETCDF_FCFLAGS@ # Archiver flags: ARFLAGS= @ARFLAGS@ @@ -62,6 +63,7 @@ silent_DEPGEN= @echo " DEPGEN " $@; silent_FC= @echo " FC " $@; silent_FCLD= @echo " FCLD " $@; silent_MKDIR= @echo " MKDIR " $(@D); +silent_MOD= @echo " MOD <" $<; endif # Path suffixes (i.e. without $(srcdir) prefix) of the source files: @@ -119,6 +121,7 @@ mostlyclean: $(bundled_subdirs) rm -f $(moddir)/*.@FC_MOD_FILE_EXT@ $(moddir)/*.@FC_MOD_FILE_EXT@.proxy rm -f $(moddir)/*.@FC_SMOD_FILE_EXT@ $(moddir)/*.@FC_SMOD_FILE_EXT@.sproxy rm -f $(lib_files) $(exe_files) $(exe_files:=.dSYM) +@SEPARATE_MODS_ENABLED@ rm -rf $(moddir_null) $(src_files:.f90=.modstamp) # Delete files generated at the building stage: clean: mostlyclean @@ -156,15 +159,27 @@ $(lib_files): | $(dir_files) $(silent_AR)rm -f $@ && $(AR) $(ARFLAGS) $@ $^ # Executable linking rules: -main@EXEEXT@: $(filter %.@OBJEXT@,$(shell $(DEPLIST) $(DEPLIST_args) -t $(main_obj_file) -f $(exe_dep_files))) $(lib_files) $(BUNDLED_LIBFILES) +main_prereqs:= $(shell $(DEPLIST) $(DEPLIST_args) -t $(main_obj_file) -f $(exe_dep_files)) +@SEPARATE_MODS_ENABLED@main_prereqs:= $(filter %.@OBJEXT@ %.modstamp,$(main_prereqs)) +@SEPARATE_MODS_ENABLED@main_prereqs:= $(sort $(main_prereqs:.modstamp=.@OBJEXT@)) +@SEPARATE_MODS_DISABLED@main_prereqs:= $(filter %.@OBJEXT@,$(main_prereqs)) +main_prereqs+= $(lib_files) $(BUNDLED_LIBFILES) + +main@EXEEXT@: $(main_prereqs) $(exe_files): | $(dir_files) $(silent_FCLD)$(FC) -o $@ $(makefile_FCFLAGS) $(FCFLAGS) $(LDFLAGS) $+ $(makefile_LIBS) $(LIBS) # Fortran compilation rule: -%.@OBJEXT@: %.f90 | $(dir_files) $(bundled_subdirs) sanitize-mod-proxies - $(silent_FC)$(FC) -o $@ -c $(makefile_FCFLAGS) $(FCFLAGS) @FCFLAGS_f90@ $< +@SEPARATE_MODS_ENABLED@%.@OBJEXT@: %.f90 | $(dir_files) $(bundled_subdirs) sanitize-mod-proxies +@SEPARATE_MODS_ENABLED@ $(silent_FC)@MKDIR_P@ $(moddir_null)/$@ && $(FC) -o $@ -c @FC_MOD_OUT@$(moddir_null)/$@ $(makefile_FCFLAGS) $(FCFLAGS) @FCFLAGS_f90@ $< + +@SEPARATE_MODS_DISABLED@%.@OBJEXT@: %.f90 | $(dir_files) $(bundled_subdirs) sanitize-mod-proxies +@SEPARATE_MODS_DISABLED@ $(silent_FC)$(FC) -o $@ -c @FC_MOD_OUT@$(moddir) $(makefile_FCFLAGS) $(FCFLAGS) @FCFLAGS_f90@ $< +# Fortran module generation rule: +@SEPARATE_MODS_ENABLED@%.modstamp: %.f90 | $(dir_files) $(bundled_subdirs) sanitize-mod-proxies +@SEPARATE_MODS_ENABLED@ $(silent_MOD)$(FC) -c @FC_MOD_OUT@$(moddir) $(makefile_FCFLAGS) $(FCFLAGS) @FC_MOD_ONLY@ @FCFLAGS_f90@ $< && touch $@ # Fortran module file tracking rule: $(moddir)/%.@FC_MOD_FILE_EXT@.proxy: @@ -197,8 +212,11 @@ sanitize-mod-proxies: $(silent_MKDIR)@MKDIR_P@ $(@D) && touch $@ # Fortran dependency generation rule: +@SEPARATE_MODS_ENABLED@fc_mod_stamp_name= $(@:.f90.d=.modstamp) +@SEPARATE_MODS_DISABLED@fc_mod_stamp_name= $(@:.f90.d=.o) + %.f90.d: %.f90 mkhelper.mk | $(dir_files) - $(silent_DEPGEN)$(DEPGEN) $(DEPGEN_args) -o $@ --obj-name $(@:.f90.d=.@OBJEXT@) -i $< -- $(DEPGEN_FCFLAGS) $(makefile_FCFLAGS) $(FCFLAGS) + $(silent_DEPGEN)$(DEPGEN) $(DEPGEN_args) -o $@ --obj-name $(@:.f90.d=.o) --fc-mod-stamp-name $(fc_mod_stamp_name) -i $< -- $(DEPGEN_FCFLAGS) @FC_MOD_OUT@$(moddir) $(makefile_FCFLAGS) $(FCFLAGS) # Dependency generation rule for undetectable Fortran dependencies: extra_f90.d: mkhelper.mk