# FPM and preprocessor: how to pass path strings

**URL:** <https://fortran-lang.discourse.group/t/fpm-and-preprocessor-how-to-pass-path-strings/6495>\
**Category:** Help\
**Created:** [September 10, 2023, 5:52pm UTC](https://fortran-lang.discourse.group/t/fpm-and-preprocessor-how-to-pass-path-strings/6495 "2023-09-10T17:52:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![pera](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pera/32/3092_2.png) [@pera](https://fortran-lang.discourse.group/u/pera)\
**Post date:** [September 10, 2023, 5:52pm UTC](https://fortran-lang.discourse.group/t/fpm-and-preprocessor-how-to-pass-path-strings/6495/1 "2023-09-10T17:52:15Z")

</div>

Hello,

I am new here and this is my first message in the forum, which already helped me when I was stuck in writing some Fortran lines and made me curious about this language, so I would like to thank the community.

I am writing a small library for an atomic potential to be used in a molecular dynamics code, which will probably be the object of other questions, but for now I restrict myself to the potential. Despite this being a small part of a larger project, I took it as an opportunity to learn about Fortran Package Manager and unit testing for the very first time.

The potential relies on importing some external coefficients stored in a huge text file; also, when I do the tests, I import few atomic configurations from an external modified .xyz file, which is just a plain text file.

Since I don’t know in principle where the code will be placed (well I know, either in my workstation or in some subpath of my $WORKDIR on some cluster, still, different ones), I pass the path to these files through the C preprocessor, using for example the following in the Makefile:

CPPFLAGS = -Ddata\_path=‘“$(CURDIR)/tests/data/’ -cpp

I don’t know if this is the best solution, but it works. How can I achieve this using fpm?  
In particular I have two problems:

1. I tried different versions of what I found in the documentation:

```auto
  [preprocess] 
cpp.macros=[“data_path=‘tests/data/'"]  

```

But I don’t get any substitution of the string data\_path with “tests/data” in the code, instead I get an Error: Invalid character in name at (1) compilation terminated due to -fmax-errors=1.  
What is the right way to substitute a word with a string through the preprocessor? Or, is there a better way this is achieved?  
2. In the Makefile I am relying on the environment variable $CURDIR, but I can’t use it in the fpm. The relative path that I put as an example in the point 1 is relative to the fpm.toml file, but I’m still not sure if it would work when I call the executable from any place (for example, from a subpath of $SCRATCH in a cluster).

Thanks in advance for guidance!

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [September 10, 2023, 6:36pm UTC](https://fortran-lang.discourse.group/t/fpm-and-preprocessor-how-to-pass-path-strings/6495/2 "2023-09-10T18:36:59Z")

</div>

Welcome to Discourse @pera!

The syntax you’re using is exactly right (assuming the canted quotes in your example that replaced the simple ones are due to autocorrect).

However, you’re assuming that the `cpp` preprocessor can pass a string as a macro, which is unfortunately not true because gfortran only implements a subset of the cpp preprocessor, called [“traditional mode”](https://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html).

With this preprocessor, you cannot pass a string as a macro directly. We’ve had this problem in fpm too, and we’ve eventually implemented [what suggested here](https://stackoverflow.com/questions/31649691/stringify-macro-with-gnu-gfortran): some additional steps are necessary.

See fpm’s internal implementation at:

> <https://github.com/fortran-lang/fpm/blob/6811dfe69f37882e4d6e8ffec9dd7ad22c206eaa/src/fpm/fpm_release.F90#L24C33-L24C33>

This would provide a solution. However, I think in your case you don’t want to hardcode a path to your input files in the code at compilation time. So, I suggest you use [command line arguments](https://fortran-lang.org/learn/intrinsics/system/) instead, which you can then append at the end of the `fpm run` command.

---

<div class="post-metadata">

**Author:** ![gardhor](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gardhor/32/88_2.png) [@gardhor](https://fortran-lang.discourse.group/u/gardhor)\
**Post date:** [September 11, 2023, 10:09am UTC](https://fortran-lang.discourse.group/t/fpm-and-preprocessor-how-to-pass-path-strings/6495/3 "2023-09-11T10:09:28Z")

</div>

There is a simple way to make it works with fpm.

With gfortran, you can pass a string using` "'/u/toto'"` (double quote, single quote, the string, single quote, double quote). For instance, this simple code works:

> gfortran -c -cpp -D\_\_PATH=“‘/u/toto’” SRC/Util\_m.f90  
> gfortran APP/App\_cpp.f90 Util\_m.o  
> ./a.out

The Util\_m.f90 file:

```fortran
MODULE Util_m
  IMPLICIT NONE

  character (len=*), parameter :: path = &
#if defined(__PATH)
      __PATH
#else
      '~/Lib'
#endif

END MODULE Util_m

```

The main App.f90

```fortran
PROGRAM App_cpp
  USE Util_m
  IMPLICIT NONE

  write(*,*) 'path: ',path

END PROGRAM App_cpp

```

Then with fpm, you need to protect the second and the third double quote with a backslash.  
`cpp.macros = ["__PATH=\"'/u/toto'\""]`
