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.txt, native-file or cross-file.

Where possible, symlinks and parent directory notation are resolved to an absolute path.


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.


Takes a single string argument and returns true if a directory with that name exists on the file system.


Takes a single string argument and returns true if an file with that name exists on the file system.

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


since 0.54.0

Return a boolean indicating if the path string or (since 0.59.0) files() specified is absolute, WITHOUT expanding ~.


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


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.


The fs.size(filename) method returns the size of the file in integer bytes.


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.


x = 'foo.txt'
y = 'sub/../foo.txt'
z = 'bar.txt'  # a symlink pointing to foo.txt
j = 'notafile.txt'  # non-existent 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'  # non-existent 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.


since 0.54.0

A path string with a leading ~ is expanded to the user home directory


fs.expanduser('~')  # user home directory

fs.expanduser('~/foo')  # <homedir>/foo


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.


fs.as_posix('\\') == '/'  # true
fs.as_posix('\\\\') == '/'  # true

fs.as_posix('foo\\bar/baz') == 'foo/bar/baz'  # true


The replace_suffix method is a string manipulation convenient for filename modifications. It allows changing the filename suffix like:

swap suffix

original = '/opt/foo.ini'
new = fs.replace_suffix(original, '.txt')  # /opt/foo.txt

add suffix

original = '/opt/foo'
new = fs.replace_suffix(original, '.txt')  # /opt/foo.txt

compound suffix swap

original = '/opt/foo.dll.a'
new = fs.replace_suffix(original, '.so')  # /opt/foo.dll.so

delete suffix

original = '/opt/foo.dll.a'
new = fs.replace_suffix(original, '')  # /opt/foo.dll


Returns the parent directory (i.e. dirname).

new = fs.parent('foo/bar')  # foo
new = fs.parent('foo/bar/baz.dll')  # foo/bar


Returns the last component of the path (i.e. basename).

fs.name('foo/bar/baz.dll.a')  # baz.dll.a


since 0.54.0

Returns the last component of the path, dropping the last part of the suffix

fs.stem('foo/bar/baz.dll')  # baz
fs.stem('foo/bar/baz.dll.a')  # baz.dll


  • read(path, encoding: 'utf-8') (since 0.57.0): return a string 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.

The results of the search are