# How to access a subdirectory in a Win/Unix compatible way?

**URL:** <https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630>\
**Category:** fpm\
**Created:** [October 12, 2023, 3:09pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630 "2023-10-12T15:09:08Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [October 12, 2023, 3:09pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/1 "2023-10-12T15:09:08Z")

</div>

I am working on a fpm project that will contain tens of `.txt` files that can be read by the Fortran program. It seems I must put all these text files a the root of the fpm project if I want `open(newunit=file_unit, file=filename)` to access them. It runs but I am not entirely satisfied as my project root directory will be cluttered with those files.

I could put them into a `txt/` subdirectory and access them with something like `file="txt/"//filename` but I would stumble on the Unix/Windows directories separator problem and I want my project to work on all systems.

Is there a way to deal with that problem with an fpm option (for example an option changing the working directory)? I do not want to use an additional library to deal with that problem, as I want to stay simple (if there is no solution, I will live with that).

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [October 12, 2023, 3:32pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/2 "2023-10-12T15:32:28Z")

</div>

What I do is to have this parameter stored in a module

```auto
#ifdef WIN32
  character(len=1), parameter, public :: path_sep='\'
#else
  character(len=1), parameter, public :: path_sep='/'
#endif

```

then use it as needed  
`file=<something>//path_sep//<something>`

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [October 12, 2023, 3:34pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/3 "2023-10-12T15:34:41Z")

</div>

The file I/O Windows API (which I assume is used behind the scene by the Fortran compiler) supports the slash “`/`” as a separator.

> The name of the file or device to be created or opened. You may use either forward slashes (`/`) or backslashes (`\`) in this name.

[https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea)

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [October 12, 2023, 3:34pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/4 "2023-10-12T15:34:53Z")

</div>

You could determine at run-time whether the OS is Unix or Windows by checking if the PATH environment variable contains forward or back slashes. For example, on my Windows PC the output of

```auto
use iso_fortran_env
implicit none
character (len=100) :: pathstring
call get_environment_variable("PATH",pathstring)
print*,trim(pathstring)
end

```

is

`c:\Users\myname\AppData\Local\Programs\R\R-4.2.2\bin\x64;c:\programs\gnuplot\bin;c:\Users\myname`

---

<div class="post-metadata">

**Author:** ![Pap](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pap/32/1305_2.png) [@Pap](https://fortran-lang.discourse.group/u/Pap)\
**Post date:** [October 12, 2023, 4:08pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/5 "2023-10-12T16:08:03Z")

</div>

In the (distant) past I used both what @hkvzjal and @Beliavsky suggested. Both work, but I don’t think they are needed anymore. `/` works just fine in that other operating system that normally expects `\` instead. I’m using MinGW-w64 though, and occasionally TDM\_GCC - I’m not sure if that’s true for other compilers. So I don’t have to do anything special, the code is exactly the same as in Unix-like systems.

This, however, is _not_ true for Makefiles. In some cases `/` works as expected (for example, when you do the actual compiling with something like `$(FC) $(SRC_DIR)/filename.f90 ...`. But in some other cases it won’t work. For example if you want to set directories in a Makefile, you have to use, e.g., `EXE_DIR=..\bin` intstead of what you would do on Unix-like systems. This is why, while the code itself is the same, Makefiles are not.

What I do is to have a generic Makefile that detects the OS and sets stuff accordingly, then two Makefiles, one for GNU/Linux. BSD, etc and one for… that other operating system. The generic makefile will then include the actual Makefile in the end, depending on the OS detected. It works all the time.

For a generic Makefile, see [this](https://fortran-lang.discourse.group/t/fortran-and-freebsd/6445/18) post.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [October 12, 2023, 4:18pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/6 "2023-10-12T16:18:51Z")

</div>

> [@vmagnin](#):
>
> Is there a way to deal with that problem with an fpm option (for example an option changing the working directory)?

There is a flag for this purpose:

```txt
 -C, --directory PATH
             Change working directory to PATH before running any command

```

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [October 12, 2023, 5:46pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/7 "2023-10-12T17:46:02Z")

</div>

I knew this was on a TODO list somewhere, but I was unaware this got added. Thanks for reminder.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [October 12, 2023, 7:00pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/8 "2023-10-12T19:00:25Z")

</div>

Thanks @hkvzjal , @PierU , @Pap , @Beliavsky  
It’s true I had noticed that the `/` can be used in the Windows Powershell. If that solves the problem in Fortran programs, it’s “one giant leap for mankind”! In MinGW environments, it should evidently not be a problem, but if it is the same with Powershell, let’s have a drink!

Thanks @ivanpribec , it’s an option I will note for another project.  
In the present case, I just realized my idea was stupid as my project will be a library. So when it is used as a fpm dependency, we can not have a working directory for that library that would be different of the working directory of the parent project, as there is only one executable.  
But wait, it seems therefore still worse: if I use that library as a fpm dependency, the final executable will not try to read my `.txt` files in the root directory of my library, isn’t it? It will try to read in the root directory of the parent project, I guess… 🥴

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [October 12, 2023, 7:08pm UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/9 "2023-10-12T19:08:27Z")

</div>

I have just tried in Windows 10: in its file manager, you can type a path containing both `\` and `/` and it works. 🍾

---

<div class="post-metadata">

**Author:** ![Pap](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pap/32/1305_2.png) [@Pap](https://fortran-lang.discourse.group/u/Pap)\
**Post date:** [October 13, 2023, 4:56am UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/10 "2023-10-13T04:56:13Z")

</div>

> [@vmagnin](#):
>
> In MinGW environments, it should evidently not be a problem, but if it is the same with Powershell, let’s have a drink!

Is there a special reason you need Powershell? I’m asking because I never used it, at least not for building/installing Fortran applications/libraries. I am using Emacs’ built-in terminals (it has two kinds of them, actually) and both work with `/` for everything. I know you are a Vim user, and if I remember correctly it does have a shell via plugins. Also Neovim seems to have such functionality built-in.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [October 13, 2023, 7:40am UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/11 "2023-10-13T07:40:45Z")

</div>

> [@Pap](#):
>
> Is there a special reason you need Powershell?

No, I am just trying to figure out how modern Windows manages directory paths because I want my Fortran library to work everywhere. It’s not a personal need…

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [October 13, 2023, 7:47am UTC](https://fortran-lang.discourse.group/t/how-to-access-a-subdirectory-in-a-win-unix-compatible-way/6630/12 "2023-10-13T07:47:56Z")

</div>

Well, I will revise my strategy. My `.txt` files should be read and be put into arrays of integers. I think I will transform them into Fortran code, it will be easier to manage (no path working directory problem). Usually, I would have written a Python script, but this time I will recycle the small subroutine I had written in Fortran to read them, to generate a Fortran module declaring those arrays. A Fortran code generating a Fortran code is more fun!
