mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.51k stars 1.6k forks source link

How to install Fortran .mod files? #5374

Open tschoonj opened 5 years ago

tschoonj commented 5 years ago

I can't seem to figure out how to install the Fortran module files that are generated during the build.

Not sure if it matters, but I am building a library that is made up from C, C++ and Fortran code, all of which works fine, the Fortran unit tests compilation also has no problem finding the .mod files.

Any thoughts? Apologies if this has been covered elsewhere already...

scivision commented 5 years ago

https://github.com/mesonbuild/meson/issues/4708 is the same issue i believe. This might not be in Meson yet. A workaround would be to call a Python script that copies them over.

vmagnin commented 5 years ago

See also: https://groups.google.com/forum/#!topic/mesonbuild/YbksVEvL--Y A workaround using install_subdir() is proposed, waiting for a better and cleaner solution.

vmagnin commented 5 years ago

In my gtk-fortran project, I am using the following workaround:

install_subdir(meson.build_root()/'src'/'25a6634@'/gtk_V_fortran+'@sha',
                install_dir: 'include'/gtk_V_fortran,
                strip_directory: true,
                exclude_files: ['src_atk-auto.f90.o', 'src_gdk-pixbuf-auto.f90.o', 'src_gtk.f90.o'...])

The problem is that these .mod files are generated in the directory gtk-fortran/buildmeson/src/25a6634@@gtk-3-fortran@sha. I don't know how Meson derived the prefix 25a6634@ but I am afraid it could be different on another machine...

So, I tried to write something like:

install_subdir(shared_lib.private_dir_include(),...`

but I obtained the message src/meson.build:78:0: ERROR: Arguments must be strings, because .private_dir_include() returns what is called an "opaque value" instead of a string.

Is it possible to obtain a string from .private_dir_include() ?

scivision commented 5 years ago

That's a good thought I had also tried private_dir. It seems possible an internal modification to Meson might be able to do it.

awvwgk commented 3 years ago

Is there a way forward for this long-standing issue? private_dir_include() so far works sufficiently well when all projects are in meson, but after installation this isn't an option anymore.

awvwgk commented 3 years ago

The easiest way to install module files seems to be with an install script

meson.add_install_script(
  find_program(files('install-mod.py')),
  get_option('includedir') / meson.project_name(),
)

To find and copy all module from the target's private directories in the build root directories or in the complete build tree this script worked for me:

#!/usr/bin/env python
# SPDX-Identifier: CC0-1.0
from os import environ, listdir, makedirs, walk
from os.path import join, isdir, exists
from sys import argv
from shutil import copy

all_modules = True

build_dir = environ["MESON_BUILD_ROOT"]
if "MESON_INSTALL_DESTDIR_PREFIX" in environ:
    install_dir = environ["MESON_INSTALL_DESTDIR_PREFIX"]
else:
    install_dir = environ["MESON_INSTALL_PREFIX"]

include_dir = argv[1] if len(argv) > 1 else "include"
module_dir = join(install_dir, include_dir)

modules = []
if all_modules:
    # finds $build_dir/**/*.mod
    for root, dirs, files in walk(build_dir):
        modules += [join(root, f) for f in files if f.endswith(".mod")]
else:
    # finds $build_dir/*/*.mod
    for d in listdir(build_dir):
        bd = join(build_dir, d)
        if isdir(bd):
            modules += [join(bd, f) for f in listdir(bd) if f.endswith(".mod")]

if not exists(module_dir):
    makedirs(module_dir)

for mod in modules:
    print("Installing", mod, "to", module_dir)
    copy(mod, module_dir)