1#!/usr/bin/env python3 2 3# External command, intended to be called with run_command(), custom_target(), 4# meson.add_install_script() and meson.add_dist_script(). 5 6# argv[1] argv[2:] 7# handle-built-files.py <subcommand> <xxx>... 8 9import os 10import sys 11import shutil 12import subprocess 13from pathlib import Path 14 15subcommand = sys.argv[1] 16 17# Invoked from custom_target() in meson.build. 18def build_from_m4(): 19 # argv[2] argv[3] argv[4] argv[5] 20 # <include_dir> <input_file> <output_file> <stamp_file> 21 22 include_dir = sys.argv[2] 23 input_file = sys.argv[3] 24 output_file = sys.argv[4] 25 stamp_file = sys.argv[5] 26 27 # Create the destination directory, if it does not exist. 28 output_dir = os.path.dirname(output_file) 29 os.makedirs(output_dir, exist_ok=True) 30 31 cmd = [ 32 'm4', 33 '-I', include_dir, 34 input_file, 35 ] 36 output_file_obj = open(output_file, mode='w') 37 result = subprocess.run(cmd, stdout=output_file_obj) 38 output_file_obj.close() 39 40 if result.returncode: 41 return result.returncode 42 43 if stamp_file.endswith('.cc'): 44 shutil.copy(output_file, stamp_file) 45 else: 46 Path(stamp_file).touch(exist_ok=True) 47 return 0 48 49# Invoked from meson.add_install_script(). 50def install_built_h_files(): 51 # argv[2] argv[3] argv[4:] 52 # <built_h_dir> <install_subdir> <built_h_files>... 53 54 # <built_h_dir> is an absolute path in the build directory or source directory. 55 # <install_subdir> is an installation directory, relative to {prefix}. 56 built_h_dir = sys.argv[2] 57 install_dir_root = os.path.join(os.getenv('MESON_INSTALL_DESTDIR_PREFIX'), sys.argv[3]) 58 59 for file in sys.argv[4:]: 60 path_h = os.path.join(built_h_dir, file) 61 rel_dir = os.path.dirname(file) 62 if rel_dir: 63 install_dir = os.path.join(install_dir_root, rel_dir) 64 else: 65 install_dir = install_dir_root 66 print('Installing ', path_h, ' to ', install_dir) 67 68 # Create the installation directory, if it does not exist. 69 os.makedirs(install_dir, exist_ok=True) 70 71 # shutil.copy2() copies timestamps and some other file metadata. 72 shutil.copy2(path_h, install_dir) 73 return 0 74 75# Invoked from meson.add_dist_script(). 76def dist_built_files(is_msvc_files=False): 77 # argv[2] argv[3] argv[4:] 78 # <built_h_cc_dir> <dist_dir> <built_files>... 79 80 # <built_h_cc_dir> is an absolute path in the build directory or source directory. 81 # <dist_dir> is a distribution directory, relative to MESON_DIST_ROOT. 82 built_h_cc_dir = sys.argv[2] 83 dist_dir_root = os.path.join(os.getenv('MESON_DIST_ROOT'), sys.argv[3]) 84 dist_dir = dist_dir_root 85 86 # Distribute .h and .cc files built from .m4 files, or generated MSVC files. 87 for file in sys.argv[4:]: 88 if not is_msvc_files: 89 dist_dir = os.path.join(dist_dir_root, os.path.dirname(file)) 90 91 # Create the distribution directory, if it does not exist. 92 os.makedirs(dist_dir, exist_ok=True) 93 94 shutil.copy(os.path.join(built_h_cc_dir, file), dist_dir) 95 return 0 96 97# Invoked from run_command() in meson.build. 98def copy_built_files(): 99 # argv[2] argv[3] argv[4:] 100 # <from_dir> <to_dir> <file_names>... 101 102 # <from_dir> is an absolute or relative path of the directory to copy from. 103 # <to_dir> is an absolute or relative path of the directory to copy to. 104 from_dir_root = sys.argv[2] 105 to_dir_root = sys.argv[3] 106 107 # Copy some built files if they exist in from_dir, but not in the destination 108 # directory, or if they are not up to date in the destination directory. 109 # (The term "source directory" is avoided here, because from_dir might not 110 # be what Meson calls a source directory as opposed to a build directory.) 111 112 # Copy .h and .cc files built from .m4 files. 113 for file in sys.argv[4:]: 114 from_file = os.path.join(from_dir_root, file) 115 to_file = os.path.join(to_dir_root, file) 116 if os.path.isfile(from_file) and ((not os.path.isfile(to_file)) 117 or (os.stat(from_file).st_mtime > os.stat(to_file).st_mtime)): 118 119 # Create the destination directory, if it does not exist. 120 os.makedirs(os.path.dirname(to_file), exist_ok=True) 121 122 shutil.copy(from_file, to_file) 123 return 0 124 125# ----- Main ----- 126if subcommand == 'build_from_m4': 127 sys.exit(build_from_m4()) 128if subcommand == 'install_built_h_files': 129 sys.exit(install_built_h_files()) 130if subcommand == 'dist_built_files': 131 sys.exit(dist_built_files()) 132if subcommand == 'copy_built_files': 133 sys.exit(copy_built_files()) 134if subcommand == 'dist_gen_msvc_files': 135 sys.exit(dist_built_files(True)) 136print(sys.argv[0], ': illegal subcommand,', subcommand) 137sys.exit(1) 138