How to copy a file in Meson to a subdirectory
Asked Answered
C

2

6

My application uses a Glade file and also cached data in a JSON file. When I do the following, everything works okay as long as the user installs the application with ninja install

    #Install cached JSON file
    install_data(
        join_paths('data', 'dataCache.json'),
        install_dir: join_paths('myapp', 'resources')
    )
    #Install the user interface glade file
    install_data(
        join_paths('src', 'MainWindow.glade'),
        install_dir: join_paths('myapp', 'resources')
    )

The downside is that the user needs to install the application. I want the user to be able to just build the application with ninja and run it without installing it if they don't want to install it on their system. The problem is that when I do

    #Copy the cached JSON file to the build output directory
    configure_file(input : join_paths('data', 'dataCache.json'),
        output : join_paths('myapp', 'resources', 'dataCache.json'),
        copy: true
    )

    #Copy the Glade file to the build output directory
    configure_file(input : join_paths('src', 'MainWindow.glade'),
        output : join_paths('myapp', 'resources', 'MainWindow.glade'),
        copy: true
    )

I get ERROR: Output file name must not contain a subdirectory.

Is there a way to run ninja and have it create the directories myapp/resources on the build folder and then copy the Glade and JSON file there to be used as resources? Such as to let the user run the application without having to do ninja install?

Contrayerva answered 8/4, 2020 at 14:23 Comment(0)
P
3

You can do it by making a script and call it from Meson.

For example, in a file copy.py that takes the relative input and output paths as arguments:

#!/usr/bin/env python3 

import os, sys, shutil

# get absolute input and output paths
input_path = os.path.join(
    os.getenv('MESON_SOURCE_ROOT'), 
    os.getenv('MESON_SUBDIR'),
    sys.argv[1])

output_path = os.path.join(
    os.getenv('MESON_BUILD_ROOT'), 
    os.getenv('MESON_SUBDIR'),
    sys.argv[2])

# make sure destination directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True)

# and finally copy the file
shutil.copyfile(input_path, output_path)

and then in your meson.build file:

copy = find_program('copy.py')

run_command(
    copy,
    join_paths('src', 'dataCache.json'), 
    join_paths('myapp', 'resources', 'dataCache.json')
)
run_command(
    copy, 
    join_paths('src', 'MainWindow.glade'), 
    join_paths('myapp', 'resources', 'MainWindow.glade')
)
Pardoner answered 9/4, 2020 at 19:23 Comment(0)
S
5

https://mesonbuild.com/Fs-module.html#copyfile

copy = fs.copyfile('input-file', 'output-file')
Sisal answered 23/6, 2023 at 3:11 Comment(0)
P
3

You can do it by making a script and call it from Meson.

For example, in a file copy.py that takes the relative input and output paths as arguments:

#!/usr/bin/env python3 

import os, sys, shutil

# get absolute input and output paths
input_path = os.path.join(
    os.getenv('MESON_SOURCE_ROOT'), 
    os.getenv('MESON_SUBDIR'),
    sys.argv[1])

output_path = os.path.join(
    os.getenv('MESON_BUILD_ROOT'), 
    os.getenv('MESON_SUBDIR'),
    sys.argv[2])

# make sure destination directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True)

# and finally copy the file
shutil.copyfile(input_path, output_path)

and then in your meson.build file:

copy = find_program('copy.py')

run_command(
    copy,
    join_paths('src', 'dataCache.json'), 
    join_paths('myapp', 'resources', 'dataCache.json')
)
run_command(
    copy, 
    join_paths('src', 'MainWindow.glade'), 
    join_paths('myapp', 'resources', 'MainWindow.glade')
)
Pardoner answered 9/4, 2020 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.