# Multiple Build Invocations Required to Compile?

**URL:** https://discourse.cmake.org/t/multiple-build-invocations-required-to-compile/9301
**Category:** Code
**Tags:** lang:fortran
**Created:** [October 27, 2023, 11:45pm UTC](https://discourse.cmake.org/t/multiple-build-invocations-required-to-compile/9301 "2023-10-27T23:45:27Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![KTRR](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/848f3c/32.png) [@KTRR](https://discourse.cmake.org/u/KTRR)
#### Post date: [October 27, 2023, 11:45pm UTC](https://discourse.cmake.org/t/multiple-build-invocations-required-to-compile/9301/1 "2023-10-27T23:45:27Z")

</div>

I’m running into an issue where multiple build invocations are required to complete compilation (because modules are not being compiled in the correct order). I’m using CMake 3.27.7 and Ninja 1.11.1 on Windows with the latest OneAPI Intel classic Fortran compiler (ifort).

I’m new to CMake, so this is almost certainly a PEBCAK issue, but I’m at a loss as to how best to resolve it. I’ve made a MWE, but unfortunately lack the permissions to attach it. But the primary structure is:

```auto
src
     library1
        CMakeLists.txt
        module1A.f90
        module1B.f90
    library2
        CMakeLists.txt
        module2A.f90
test
    library1
        CMakeLists.txt
        test_library1.f90
    library2
        CMakeLists.txt
        test_library1.f90
CMakeLists.txt        

```

The library1 CMakeLists.txt file looks like:

```auto
add_library(${library1Name} module1A.f90 module1B.f90)
set_target_properties(${library1Name} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(${library1Name} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

```

The library2 CMakeLists.txt is basically identical:

```auto
add_library(${library2Name} module2A.f90)
set_target_properties(${library2Name} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/library2)
target_include_directories(${library2Name} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/library2)

```

There are dependencies between the libraries via modules as (module1A.f90):

```auto
module module1A
    implicit none
    integer, parameter :: MODULE_1A_PARAMETER = 1
end module module1A

```

and module1B.f90:

```auto
module module1B
    use module2A, only : MODULE_2A_PARAMETER
    implicit none
    integer, parameter :: MODULE_1B_PARAMETER = MODULE_2A_PARAMETER + 2
end module module1B

```

and module2A.f90:

```auto
module module2A
    use module1A, only : MODULE_1A_PARAMETER
    implicit none
    integer, parameter :: MODULE_2A_PARAMETER = MODULE_1A_PARAMETER + 1
end module module2A

```

The test\library1\CMakeLists.txt only adds library1:

```auto
add_executable(test_library1 test_library1.f90)
target_link_libraries(test_library1 PUBLIC ${library1Name})

```

And the test\_library1.f90 is simply:

```auto
program test_library1
    use module1A, only : MODULE_1A_PARAMETER
    use module1B, only : MODULE_1B_PARAMETER

    implicit none

    write(*,*) "MODULE_1A_PARAMETER = ", MODULE_1A_PARAMETER
    write(*,*) "MODULE_1B_PARAMETER = ", MODULE_1B_PARAMETER
end program test_library1

```

The test\library2 CMakeLists.txt is basically identical:

```auto
add_executable(test_library2 test_library2.f90)
target_link_libraries(test_library2 ${library2Name})

```

As is test\_library2.f90:

```auto
program test_library2
    use module2A, only : MODULE_2A_PARAMETER

    implicit none

    write(*,*) "MODULE_2A_PARAMETER = ", MODULE_2A_PARAMETER
end program test_library2

```

The issue is obviously that `library1` and `library2` depend on each other. The root CMakeLists.txt attempts to resolve this as:

```auto
cmake_minimum_required(VERSION 3.27.7)

project(moduleTest LANGUAGES Fortran)

set(library1Name library1)
set(library2Name library2)

add_subdirectory(src)
add_subdirectory(test)

target_link_libraries(${library1Name} ${library2Name})
target_link_libraries(${library2Name} ${library1Name})

```

Obviously this is wrong, since although it can compile, it requires multiple build invocations to successfully do so (the first build invocation will complain that `MODULE_1A_PARAMETER` in `module2A.f90` does not exist).

Is there a canonical or “best practices” way of handling this kind of circular dependency?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 29, 2023, 12:17pm UTC](https://discourse.cmake.org/t/multiple-build-invocations-required-to-compile/9301/2 "2023-10-29T12:17:05Z")

</div>

There’s no support for cycles in the module dependency graph at the target level. In the build graph, this would end up as a cycle between the collation outputs of each target (as they’d need each others’ output to know about the other). I suggest that you break up the `module1` modules into separate libraries so that the cycle can be broken.
