# FS (filesystem) module This module provides functions to inspect the file system. It is available starting with version 0.53.0. Since 0.59.0, all functions accept `files()` objects if they can do something useful with them (this excludes `exists`, `is_dir`, `is_file`, `is_absolute` since a `files()` object is always the absolute path to an existing file). ## File lookup rules Non-absolute paths are looked up relative to the directory where the current `meson.build` file is. If specified, a leading `~` is expanded to the user home directory. Environment variables are not available as is the rule throughout Meson. That is, $HOME, %USERPROFILE%, $MKLROOT, etc. have no meaning to the Meson filesystem module. If needed, pass such variables into Meson via command line options in `meson.options`, native-file or cross-file. Where possible, symlinks and parent directory notation are resolved to an absolute path. ### exists Takes a single string argument and returns true if an entity with that name exists on the file system. This can be a file, directory or a special entry such as a device node. ### is_dir Takes a single string argument and returns true if a directory with that name exists on the file system. ### is_file Takes a single string argument and returns true if an file with that name exists on the file system. ### is_symlink Takes a single string or (since 0.59.0) `files()` argument and returns true if the path pointed to by the string is a symbolic link. ## File Parameters ### is_absolute *since 0.54.0* Return a boolean indicating if the path string or (since 0.59.0) `files()` specified is absolute, WITHOUT expanding `~`. Examples: ```meson fs.is_absolute('~') # false home = fs.expanduser('~') fs.is_absolute(home) # true fs.is_absolute(home / 'foo') # true, even if ~/foo doesn't exist fs.is_absolute('foo/bar') # false, even if ./foo/bar exists ``` ### hash The `fs.hash(filename, hash_algorithm)` method returns a string containing the hexadecimal `hash_algorithm` digest of a file. `hash_algorithm` is a string; the available hash algorithms include: md5, sha1, sha224, sha256, sha384, sha512. ### size The `fs.size(filename)` method returns the size of the file in integer bytes. ### is_samepath The `fs.is_samepath(path1, path2)` returns boolean `true` if both paths resolve to the same path. For example, suppose path1 is a symlink and path2 is a relative path. If `path1` can be resolved to `path2`, then `true` is returned. If `path1` is not resolved to `path2`, `false` is returned. If `path1` or `path2` do not exist, `false` is returned. Examples: ```meson x = 'foo.txt' y = 'sub/../foo.txt' z = 'bar.txt' # a symlink pointing to foo.txt j = 'notafile.txt' # nonexistent file fs.is_samepath(x, y) # true fs.is_samepath(x, z) # true fs.is_samepath(x, j) # false p = 'foo/bar' q = 'foo/bar/baz/..' r = 'buz' # a symlink pointing to foo/bar s = 'notapath' # nonexistent directory fs.is_samepath(p, q) # true fs.is_samepath(p, r) # true fs.is_samepath(p, s) # false ``` ## Filename modification The files need not actually exist yet for these path string manipulation methods. ### expanduser *since 0.54.0* A path string with a leading `~` is expanded to the user home directory Examples: ```meson fs.expanduser('~') # user home directory fs.expanduser('~/foo') # /foo ``` ### as_posix *since 0.54.0* `fs.as_posix(path)` assumes a Windows path, even if on a Unix-like system. Thus, all `'\'` or `'\\'` are turned to '/', even if you meant to escape a character. Examples ```meson fs.as_posix('\\') == '/' # true fs.as_posix('\\\\') == '/' # true fs.as_posix('foo\\bar/baz') == 'foo/bar/baz' # true ``` ### replace_suffix The `replace_suffix` method is a *string manipulation* convenient for filename modifications. It allows changing the filename suffix like: #### swap suffix ```meson original = '/opt/foo.ini' new = fs.replace_suffix(original, '.txt') # /opt/foo.txt ``` #### add suffix ```meson original = '/opt/foo' new = fs.replace_suffix(original, '.txt') # /opt/foo.txt ``` #### compound suffix swap ```meson original = '/opt/foo.dll.a' new = fs.replace_suffix(original, '.so') # /opt/foo.dll.so ``` #### delete suffix ```meson original = '/opt/foo.dll.a' new = fs.replace_suffix(original, '') # /opt/foo.dll ``` ### parent Returns the parent directory (i.e. dirname). ```meson new = fs.parent('foo/bar') # foo new = fs.parent('foo/bar/baz.dll') # foo/bar ``` ### name Returns the last component of the path (i.e. basename). ```meson fs.name('foo/bar/baz.dll.a') # baz.dll.a ``` ### stem *since 0.54.0* Returns the last component of the path, dropping the last part of the suffix ```meson fs.stem('foo/bar/baz.dll') # baz fs.stem('foo/bar/baz.dll.a') # baz.dll ``` ### read - `read(path, encoding: 'utf-8')` *(since 0.57.0)*: return a [string](Syntax.md#strings) with the contents of the given `path`. If the `encoding` keyword argument is not specified, the file specified by `path` is assumed to be utf-8 encoded. Binary files are not supported. The provided paths should be relative to the current `meson.current_source_dir()` or an absolute path outside the build directory is accepted. If the file specified by `path` changes, this will trigger Meson to reconfigure the project. If the file specified by `path` is a `files()` object it cannot refer to a built file. ### copyfile *Since 0.64.0* Copy a file from the source directory to the build directory at build time Has the following positional arguments: - src `File | str`: the file to copy Has the following optional arguments: - dest `str`: the name of the output file. If unset will be the basename of the src argument Has the following keyword arguments: - install `bool`: Whether to install the copied file, defaults to false - install_dir `str`: Where to install the file to - install_tag: `str`: the install tag to assign to this target - install_mode `array[str | int]`: the mode to install the file with returns: - a [[custom_target]] object ```meson copy = fs.copyfile('input-file', 'output-file') ```