The compilers are just being nitpicky. How could a comment be not standard-conforming? CMake has an option relevant to this task. But I have never used it, and I do not know if it also applies to Fortran.
(@FortranFan, do you have other posts showing the usage of module-definition files?)
Here is the explanation of the solution used from the CMake file of PRIMA:
# On Windows, when building shared libs, visible functions must be explicitly listed.
# Unlike C there are no standard keywords to do this in Fortran but only compiler-specific pragmas:
# !GCC$ attributes dllexport :: bobyqa_c
# !DEC$ attributes dllexport :: bobyqa_c
# the downside is unwanted -Wattribute warnings.
# Another option is to use .def files referencing exported symbols:
# https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files?view=msvc-170
# Mangling is different between GNU and Intel/LLVM compiler families so we use a dedicated file for each.
# Symbol names can be seen in object files with the dumpbin tool (or objdump) to write a new .def:
# dumpbin /symbols cobyla.f90.obj
# 017 00000000 UNDEF no_type External | COBYLA_MOD_mp_COBYLA
# x86_64-w64-mingw32-objdump -t cobyla.f90.obj
# [ 4](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x000000000000218b __cobyla_mod_MOD_cobyla
It would be nice mentioning the DEF files in the Fortran-Lang mini book on Managing libraries.
I agree with @shahmoradi that throwing a warning for what is essentially a comment is questionable. It would be worth bringing this up on the Intel forum.
I agree with @shahmoradi that throwing a warning for what is essentially a comment is questionable. It would be worth bringing this up on the Intel forum.
This has been discussed on the Intel forum. I cannot find the particular post at the moment, but I read it yesterday. Intel regards directives as “funny-looking code” rather than “funny-looking comments”. Maybe Intel colleagues here can give more insights.
False warnings can be annoying and give the wrong impression to users of the software.
In C++ they have introduced attributes as a way to provide additional information to the compiler, to clarify usage and silence warnings.
For example if one has an interface expecting a callback, but one of the arguments is unused, the compiler will issue warnings about an unused argument:
int foo([[maybe_unused]] int bar) { // silence warning, bar is unused
return 42;
}
A second example is when preprocessing is involved; compiling in release mode with NDEBUG, assertions are removed, and a false warning would be issued:
void foo(int i, [[maybe_unused]] int j) {
assert(i == j);
// j not used further on
}
Module-definition or DEF files (*.def) are text files describing attributes of a dynamic-link library (DLL) (the shared library concept for the Windows operating system). They are a Windows concept not tied to CMake.
Similar to how Fortran has public and private attributes for module variables and procedures, you can think of module-definition files or the __declspec(dllexport) attribute as way to enforce storage-class attributes on items (functions, data) which are to be part of a shared library.
There are several reasons why fine-grained control of symbol visibility is needed
enforcing the public/private nature of an API
security concerns and protecting intelectual property (e.g. exposing names of internal subroutines could give away information)
shared library performance; i.e. the linker can discard symbols which it is sure are not used, resulting in a smaller binary object and faster startup times
I suppose it could export a DEF file, given a list of symbols. But you arrive at the same problem, either you introduce an an attribute !fpm$ dllexport, meaning fpm needs a parser and also has to know about the compiler name mangling, or you put this information into the fpm.toml manifest, re-inventing the DEF file syntax in the fpm manifest schema.
PRIMA team may want to follow up again with Intel Fortran support at their forum for their current thinking and feedback on this and decide on the best course of action.
My recommendation is to avoid cluttering Fortran code with preprocessor directives as much as possible. In the case of Windows OS and dynamic (shared) library exported symbols, I recommend the Microsoft module definition .DEF file solution as shown here.
Note the warning is issued by the Intel Fortran compiler when the compiler option -stand is in effect. Additionally, Intel provides an option to suppress this specific warning via the compiler option -Qdiag-disable:7025.
module m
contains
subroutine sub()
!dir$ attributes dllexport :: sub
end subroutine
end module
Note no warning when -stand is not applied:
C:\temp>ifort /c /standard-semantics /free m.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\temp>ifort /c /standard-semantics /free /stand m.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
m.f(4): warning #7025: This directive is not standard F2018.
!dir$ attributes dllexport :: sub
---------^
C:\temp>
And the warning can be suppressed - if you so choose - using -Qdiag-disable
C:\temp>ifort /c /standard-semantics /free /stand /Qdiag-disable:7025 m.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\temp>
We had an extensive discussion about this in the past, and decided that directives are “funny-looking statements” and not comments, and that the warnings were appropriate.
[from Steven_L_Intel1, Employee]
So the opinion of Intel seems quite clear to me. I am not sure re-posting the same question would change it a lot.