Calling procedure from included .mod file, without explicit `use` statement

So in that case, with the USE statement removed and the IMPLICIT statement added, go ahead and copy bracket(3) into your file, rename it to bracket_dup, add “external bracket_dup” and change the call from “bracket” to “bracket_dup” might be simple enough (depends on your code) to avoid the problem; which sounds somewhat close to the original plan (?). There are alternatives, like making it a CONTAINED procedure, etc.

1 Like

Perfect, I (you) may have found the culprit.

$ cat testCGfit.f90.003t.original | grep bracket

This command has no output. Does it mean that the actual driver program does not need bracket to be linked? Probably what is really happening is that it just remains unlinked, for that it is not really needed in the program (but with the implicit none(type, external) in that module I cannot nevertheless compile since it fails at an earlier stage, due to the requested higher strictness.

And thanks so much for this clear cut statement. It solves the main doubt for me.

Very similarly:

$ objdump -x testCGfit | grep -i bracket

Did not print anything.

Hence the surprise point moves… now I understand why I did not need a copy of bracket inside my test code. With the Makefile it just compiles and runs with no problems whatsoever and, as we can see with both objdump and -fdump-tree-original, there is no trace of bracket in the final executable. Fine.

Then the question moves to: why does fpm fail to compile my driver program as a test, specifically complaining about bracket?

[gbellomi@login2 Test_CGfit]$ fpm clean
Delete build, excluding dependencies (y/n)? y
 + rm -rf build/mpif90_9892AC5BA6456D09
[gbellomi@login2 Test_CGfit]$ 
[gbellomi@login2 Test_CGfit]$ 
[gbellomi@login2 Test_CGfit]$ fpm test --flag "$(pkg-config --cflags scifor) $(pkg-config --libs scifor)"
minimize_krauth.f                      done.
optimize_cgfit_routines.f90            done.
minimize_sascha.f                      done.
VARS_GLOBAL.f90                        done.
OPTIMIZATION.f90                       done.
BATH_AUX.f90                           done.
BATH_FIT.f90                           done.
libCGfit.a                             done.
testCGfit.f90                          done.
testCGfit                              failed.
[100%] Compiling...
build/gfortran_07A77609A9445D9C/CGfit/test_testCGfit.f90.o: In function `MAIN__':
[... < other problems that here are off-topic > ...]
build/gfortran_07A77609A9445D9C/CGfit/libCGfit.a(src_optimize_cgfit_routines.f90.o): In function `__cgfit_routines_MOD_dbrent_nograd':
optimize_cgfit_routines.f90:(.text+0xe41): undefined reference to `bracket_'
optimize_cgfit_routines.f90:(.text+0xed3): undefined reference to `bracket_'
build/gfortran_07A77609A9445D9C/CGfit/libCGfit.a(src_optimize_cgfit_routines.f90.o): In function `__cgfit_routines_MOD_dbrent_wgrad':
optimize_cgfit_routines.f90:(.text+0x117e): undefined reference to `bracket_'
optimize_cgfit_routines.f90:(.text+0x1214): undefined reference to `bracket_'
build/gfortran_07A77609A9445D9C/CGfit/libCGfit.a(src_optimize_cgfit_routines.f90.o): In function `__cgfit_routines_MOD_brent':
optimize_cgfit_routines.f90:(.text+0x1bff): undefined reference to `bracket_'
build/gfortran_07A77609A9445D9C/CGfit/libCGfit.a(src_optimize_cgfit_routines.f90.o):optimize_cgfit_routines.f90:(.text+0x1c95): more undefined references to `bracket_' follow
collect2: error: ld returned 1 exit status
<ERROR> Compilation failed for object " testCGfit "
<ERROR>stopping due to failed compilation
STOP 1

This is what originally made me search for bracket in the code, find that I forgot to copy it, etcetera… But given that make succeeds to compile (and it runs fine) this might be a “me vs fpm” problem afterall, so it might be better to close here and open a new post. The only caveat is that I don’t know what compiler flags fpm is passing to gfortran, so I should pass exactly the same as in my Makefile to really compare, i.e.

-O0 -p -g -fimplicit-none -Wsurprising  -Waliasing -fwhole-file -fcheck=all -pedantic -fbacktrace -ffree-line-length-none

Well, to the question about what options fpm(1) uses, add “–verbose”. If your code can also compile with the debug flags add “–profile debug”. Once you add flags manually, the default switches are no longer applied unless you explicitly add a profile. That will give you the flags to give you the line numbers where the calls occur.

Thanks. I inspected what are the default flags for the fpm test command and copied them to my Makefile. Eveything still builds and runs fine with make, though some warning has popped up.

I think with fpm I have subtle problems with included files (apparently they cannot be just in src/, together with the other .f90 files. I’ll try moving them in a include/ folder and see what happens…

I might open another thread if I keep having trouble with fpm test, but here I think I solved all my doubts. Thanks to all, really, I’ve learnt a lot of details about the actual build pipeline. You’re such a lovely community! <3

I marked as solution the post where I quote the precise statement by @kargl that has shed light on the original doubt quoted in the title / original post, since I find anyone landing here would like to read that before anything else. Thanks again!

1 Like

@urbanjost can I ask you an unrelated curiosity?

I see that you often append a “(n)” segment to “technical names”, like as in fpm(1), or bracket(3) above. What does that mean? (I’m wondering about that for some time, I’m sorry if it sound totally out of context here… well it is).

Yep. A very strong habit that is very common in my environment but not all that common everywhere; it is basically a reflex. If I use the word size; is it the GNU command size(1), the Fortran intrinsic size(3), just the English word, … just a habit. Unless you read man-pages a lot it is understandably odd.

1 Like