0

I'm trying Meson/Ninja for what I otherwise do in make. I have source-files listed in the src variable, one of which is a program prog.f90 with the statement call ROUTINE, and the preprocessor inserts names like sub1, sub2... for different test-executables 1.x, 2.x.... Like this:

project('proj','fortran', version : '0')
flags = ['-cpp','-fmax-errors=3','-Wall','-fcheck=all','-fbacktrace','-Og', ...]
src = ['src/f1.f90', 'src/f2.f90', prog.f90, tools.f90, ...]

progs = [
    ['1.x',   '-DROUTINE=sub1'    ],
    ['2.x',   '-DROUTINE=sub2'    ],
    ['3.x',   '-DROUTINE=sub3'    ],
    ...
]

foreach p : progs
    executable(p[0],   src,fortran_args : flags + [p[1]])
endforeach

It is faster than using make but Meson/Ninja manages to use all cores for ca 1 second when changing a specific file, while make takes 2 seconds, but mostly runs on 1 core.

It seems like each executable gets its own build directory like build/1x@exe etc with all .mod and .o files matching src. And running ninja -v it seems like the file that changed is compiled as many times as there are executables. Meanwhile make only compiles it ones (but then compiles other files due to dependencies stated between objects instead of modules).

So what is the smarter way to do this?

Jonatan Öström
  • 2,428
  • 1
  • 16
  • 27

1 Answers1

0

The easiest way would be to first make a static_library() from all other sources files (i.e. everything that is not prog.f90), and to add it in the link_with kwarg of your executable.

This would end up something like this:

# Note that 'prog.f90' is no longer in here
src = files('src/f1.f90', 'src/f2.f90', 'tools.f90', ...)

# This is the static library which will only get compiled once
lib = static_library(src, fortran_args: flags)


progs = [
    ['1.x',   '-DROUTINE=sub1'    ],
    ['2.x',   '-DROUTINE=sub2'    ],
    ['3.x',   '-DROUTINE=sub3'    ],
    ...
]

foreach p : progs
    executable(p[0], 'prog.f90', fortran_args: flags + [p[1]], link_with: lib)
endforeach
nielsdg
  • 2,318
  • 1
  • 13
  • 22