# CMake on windows with mingw compilers

**URL:** <https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885>\
**Category:** Help\
**Created:** [July 1, 2022, 10:10am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885 "2022-07-01T10:10:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ashok](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@Ashok](https://fortran-lang.discourse.group/u/Ashok)\
**Post date:** [July 1, 2022, 10:10am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/1 "2022-07-01T10:10:32Z")

</div>

Hi,  
I am trying to use CMAKE on windows with mingw - gfortran complilers.  
Suppose I have a directory structure like this:

```auto
main directory:
main.f90 ! main program
CMakeLists.txt
utils ! my modules
build ! where cmake will generate build files

```

inside utils:

```auto
mymod.f90 ! my module
CMakeLists.txt

```

Now in the main directory CMakeLists.txt

```auto
cmake_minimum_required(VERSION 3.0.0)
ENABLE_LANGUAGE(Fortran)

project(first VERSION 1.0.0)

add_subdirectory(utils) 
add_executable(first
first.f90)
target_link_libraries(first PUBLIC utilities)

```

in the utils CMakeLists.txt

```auto
ENABLE_LANGUAGE(Fortran)
add_library(utilities
mymod.f90
)
target_include_directories(utilities PUBLIC include)

```

When I am trying to build and run using

```auto
cmake .. -G "MinGW Makefiles"
mingw32-make.exe first

```

I am getting the following error:

```auto
  2 | use mymod
      | 1
Fatal Error: Cannot open module file 'mymod.mod' for reading at (1): No such file or directory
compilation terminated.
mingw32-make[3]: *** [CMakeFiles\first.dir\build.make:75: CMakeFiles/first.dir/first.f90.obj] Error 1

```

Can somebody please tell me how to use CMake with Fortran

---

<div class="post-metadata">

**Author:** ![plevold](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/plevold/32/754_2.png) [@plevold](https://fortran-lang.discourse.group/u/plevold)\
**Post date:** [July 1, 2022, 10:45am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/2 "2022-07-01T10:45:26Z")

</div>

Include the following lines for all targets that include Fortran source files (replace `<target>` with your target name or a variable containing the target name, i.e. `utilities`):

```nohighlight
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)
set_property (TARGET <target>
    PROPERTY Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include
)
target_include_directories(<target> PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include)

```

If a single CMakeLists.txt creates more than one target with Fortran sources you should make sure that include directories are unique. Assuming that the variable `libname` contains the target name from `add_library`, the code below is one possible solution:

```nohighlight
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include-${libname})
set_property (TARGET ${libname}
    PROPERTY Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include-${libname}
)
target_include_directories(${libname} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include-${libname})

```

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [July 1, 2022, 10:48am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/3 "2022-07-01T10:48:54Z")

</div>

You can have a look at [GitHub - fortran-lang/stdlib-cmake-example: Integration of the Fortran standard library in CMake projects](https://github.com/fortran-lang/stdlib-cmake-example) which provides a template for using CMake with Fortran and integrating with external projects, like [stdlib](https://github.com/fortran-lang/stdlib) and [test-drive](https://github.com/fortran-lang/test-drive).

The main takeaway is that you explicitly have to define your include directories, this can be done by associating them directly with the target:

> <https://github.com/fortran-lang/stdlib-cmake-example/blob/61e5fb0a1df900d8ebfe216b0f60f1a5eeefcdf9/src/CMakeLists.txt#L33-L38>

I tried to write the CMake files in this project in a way to make them reusable, in the best case you have to only change the project name and version (you can also delete the stdlib / test-drive dependency if you don’t like to use them).

---

<div class="post-metadata">

**Author:** ![Ashok](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@Ashok](https://fortran-lang.discourse.group/u/Ashok)\
**Post date:** [July 1, 2022, 11:05am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/4 "2022-07-01T11:05:08Z")

</div>

Thanks a lot @plevold and @awvwgk .  
I am just a beginner in CMake of projects. I really appreciate your deep knowledge and effort. While I wish to understand the fortran-lang/stdlib cmake example that you have posted, please help me with this simple project to start with.  
One main directory containing main.f90 file and one subdirectory containing one module file. How to compile and link them together. Once I am able to build this - I will expand my knowledge further into the example that you have posted.  
I hope you understand.  
Thanks.

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [July 1, 2022, 11:21am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/5 "2022-07-01T11:21:53Z")

</div>

The linked repository follows fpm’s structure to layout the project, you have three target:

1. a library defined in the `src/` directory, which is installed and usable by dependent projects
2. an executable in the `app/` directory, which is also installed
3. a test driver in the `test/` directory, for creating unit tests using the test-drive framework

You can simply copy / clone the whole project and adjust these lines to your project specification

> <https://github.com/fortran-lang/stdlib-cmake-example/blob/61e5fb0/CMakeLists.txt#L4-L8>

If you don’t want stdlib, you can delete the lines here

> <https://github.com/fortran-lang/stdlib-cmake-example/blob/61e5fb0/CMakeLists.txt#L16-L18>

Any sources you want to compile are added in the CMake file in `src/CMakeLists.txt` at, make sure to include them there otherwise they will not be built:

> <https://github.com/fortran-lang/stdlib-cmake-example/blob/61e5fb0/src/CMakeLists.txt#L4-L7>

Finally there are build and installation instructions in the README at [GitHub - fortran-lang/stdlib-cmake-example: Integration of the Fortran standard library in CMake projects](https://github.com/fortran-lang/stdlib-cmake-example#installation), which should show you how to build your new CMake project, try the whole workflow. If you want to run tests, you can also use

```auto
ctest --test-dir _build --output-on-failure

```

The CMake files contain a lot of boilerplate, which I have learned over the years of using CMake. The are apparently important to have a well working CMake project which other people can also use, why we have to write all this stuff ourselves however is beyond me. Don’t worry too much about the target export and stuff like that for the moment.

Also, if you should be sick of CMake at some point, you can simply add a package manifest for the Fortran package manager (`fpm.toml`) and use the project should build directly with fpm due to the compatible layout. There happens to be a guide on using stdlib and test-drive as dependencies with fpm at [Adding dependencies — Fortran Package Manager](https://fpm.fortran-lang.org/en/tutorial/dependencies.html).

If you have any questions feel free to ask, we are always happy to help.

---

<div class="post-metadata">

**Author:** ![Ashok](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@Ashok](https://fortran-lang.discourse.group/u/Ashok)\
**Post date:** [July 1, 2022, 11:31am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/6 "2022-07-01T11:31:41Z")

</div>

Really a big thanks @awvwgk .  
Is fpm is as robust as cmake on windows ? If yes I would rather try that.  
I am asking in the sense that - is fpm able to build and link to projects that are built with linux - on windows ? or in short - is it cross platform ?

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [July 1, 2022, 11:46am UTC](https://fortran-lang.discourse.group/t/cmake-on-windows-with-mingw-compilers/3885/7 "2022-07-01T11:46:30Z")

</div>

I’m using [fpm](https://fpm.fortran-lang.org), [meson](https://mesonbuild.com) and CMake on Linux, MacOS and Windows, some people also build my software on FreeBSD so the cross-platform setup seems to work regardless of the build system.

There is no clear advice I can give you regarding the build system choice, it depends on what you want to do. For developer productivity I would recommend fpm \> meson \>\> CMake. However, meson and CMake are great if you want to do more than just Fortran, _i.e._ export a C-API and use it in other non-Fortran libraries. My usual strategy is to have both fpm and meson in my projects, fpm for daily development and meson for deployment and developing “advanced” features (exporting C bindings, shared libraries, Python extension modules, …).

Personally, I think wasting time on build systems is very unproductive, since it is time not spend developing the project, the reality is that building a project is a lot of build system tweaking because all platforms have different quirks, there are build systems which make this easy and other which make it unnecessarily hard. CMake belong in the latter category for me.
