Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can you make fpm ignore a USE statement inside a preprocessor #ifdef #endif block #773

Open
rweed opened this issue Oct 8, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@rweed
Copy link

rweed commented Oct 8, 2022

Description

I'm trying to compile a code where I have the following logic

#ifdef USE_MPI
    USE MPI
#else
#ifdef USE_MPIF90_STUBS
    USE mpif90_stubs
#endif
#endif

fpm build gives the following error

<ERROR>*cmd_build*:target error:Unable to find source for module dependency: "mpi" used by "./src/errorHandlerClass.F90"
STOP 1

Is there anyway to make fpm ignore the dependency check for anything inside a #ifdef #endif block if the macro is not defined on the compile line

This is my first attempt to use fpm. Here are a some of issues I have with it so far.

I also would like a way to ignore or blacklist individual files (issue #700 I think)

I would like to specify a file specific rule ala a makefile rule to compile
an individual file with a lower optimization or different compiler options.

maybe something like

[file-optimization-level]
a.F90 = "-O0"

or just

[file-fflags]
a.F90="-O0 -g"

I like to spread my source across several subdirectories. If I understand the required naming convention,
I would have to rename all of my modules to add the subdir name and/or create a new subdir for each individual file. While keeping all the source files in the /src root dir is O.K. for small projects, its very inconvenient for projects that might have 100 files or more total.

Expected Behaviour

Ignore dependency checks for USE statements inside #ifdef blocks if
the ifdef macro is not defined on the compile line.

Version of fpm

0.6.0

Platform and Architecture

Linux Mint 20.3

Additional Information

No response

@rweed rweed added the bug Something isn't working label Oct 8, 2022
@LKedward
Copy link
Member

LKedward commented Oct 9, 2022

Thanks for trying out fpm @rweed and for the feedback on your issues - this is really helpful for us to understand where fpm needs improvement.

For your first issue with the module error, you can add the following to your manifest file to suppress the error:

[build]
external-modules = ["mpi"]

(This tells fpm that the module mpi is not found in the current project or any of its fpm dependencies.)

The general problem of detecting used modules while respecting preprocessor directives requires some complex rework in fpm, see #469.


For specifying compiler flags on a per-file basis, this is definitely planned (see here for proposed syntax) but the implementation remains complex.


Finally, there is no enforced naming convention for source files and the directory structure. You should be able to place your source files arbitrarily within subfolders within the src directory without issue. Please let us know if you are having an issue with this.

Hope that helps!

@rweed
Copy link
Author

rweed commented Oct 9, 2022

@LKedward

Thanks.

My issue with the MPI example is when I don't want to build a parallel application. I understand the use of external-modules for codes where I would do a $(FC) -DMPI etc bu that doesn't help if -DMPI is not set.

Also, my comment on naming conventions was based on the current online PACKAGING description where it says

"This rule applies generally to any number of nested directories and modules. For example, src/a/b/c/d.f90 must define a module called a_b_c_d.

Takeaways from this example are that:

You can place your module source files in any levels of subdirectories inside src.
The module name must include the path components and the source file name--for example, src/a/b/c/d.f90 must define a module called a_b_c_d"

Has this changed. If so the online documentation needs to be changed.

@LKedward
Copy link
Member

Apologies if I'm misunderstanding you; what exactly happens if you specify external-modules = ["mpi"] and then compile with and without -DMPI? I think this should work (assuming the mpif90_stubs module is defined somewhere in your source tree.)

The external-modules field doesn't affect the compilation in any way, it only suppresses an internal check in fpm for resolving module dependencies. So regardless of whether -DMPI is set, fpm should act the same, if that makes sense?


Thanks for letting us know about the out-dated PACKAGING instructions, yes this definitely needs to be updated. (The original strict naming convention was dropped because I raised exactly the same concerns that you have here)

@davidpfister
Copy link

I faced the same issue recently.
I am using preprocessing directive to include/exclude compiler specific dependencies, e.g.

#ifdef __INTEL_COMPILER
use ifwin
#endif

and fpm fails when I am building my project with gfortran. The use dependencies should be resolved after preprocessing and not before.
For the moment I am using this workaround:

#ifdef __INTEL_COMPILER
#include <ifwin.use>
#endif

and in the ifwin.use file I just have

use ifwin

@perazz
Copy link
Contributor

perazz commented Apr 10, 2024

The standard way to handle preprocessed use cases is what pointed out by others @davidpfister:

[build]
external-modules = ["ifwin"]

the logic is also correct, because this module is not part of the package or any of its dependencies. One idea may be to contribute a mechanism to provide an additional list of compiler-available modules (similar to the intrinsic ones). They would have to be carefully checked with respect to compiler version and OS platform though

character(15), parameter :: INTRINSIC_NAMES(*) = &
['iso_c_binding ', &
'iso_fortran_env', &
'ieee_arithmetic', &
'ieee_exceptions', &
'ieee_features ', &
'omp_lib ']

@davidpfister
Copy link

@perazz, works like a charm. Thanks for the tip.
But in the end, why not simply performing the preprocessing prior to constructing the build tree?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants