VLC 4.0.0-dev
Loading...
Searching...
No Matches
Buildsystem documentation

Autotools

VLC uses the Autotools build system tools, that is composed of various tools:

  • m4
    Used for macro expansions in the configure.ac file.
  • Autoconf
    Generates the configure shell script from the configure.ac file
  • Automake
    Generates the Makefiles from the Makefile.am files
  • libtool
    Wrapper tool to abstract linker differences across different platforms

Meson

In addition to the "traditional" autotools build system, recently there has been an ongoing effort to migrate the VLC build system to meson. Currently the meson buildsystem is in an experimental state and should not be used for release builds of VLC!

However we encourage developers to try out the meson buildsystem and report any issues with it or help add missing module builds to meson.

Organization

All meson build definitions can be found in meson.build files. All options are defined in the top-level directory meson_options.txt file, which has the same syntax as the meson build files but only accepts the option() function.

Code style and conventions

  • Indentation must be used with 4 spaces, no tabs should be used.
  • Keyword arguments (named arguments) should have the : right next to them followed by a space:
    # Right
    add_project_arguments('-D_EXAMPLE', language: ['c', 'cpp', 'objc'])
    # Wrong
    add_project_arguments('-D_EXAMPLE', language : ['c', 'cpp', 'objc'])
  • For dictionaries, key and value are separated by : and spaces should be used before and after:
    # Right
    { 'key' : 'value' }
    # Wrong
    { 'key': 'value' }
  • Strings in meson must always use 'single' quotes, never use "double" quotes.
  • Do not use arrays where not necessary, especially for the files() function:
    # Right
    files('hello.c', 'world.c')
    # Wrong
    files(['hello.c', 'world.c'])
  • Dependencies found with the dependency() function must use a variable named after the library followed by the _dep suffix, those found with find_library() must use the _lib suffix:
    # Right
    foundation_dep = dependency('Foundation')
    iconv_lib = cc.find_library('iconv')
    # Wrong
    foundation_lib = dependency('Foundation')
    iconv_dep = cc.find_library('iconv')

Adding a module

VLC modules are meson dicts added to a special array named vlc_modules. To add a new module, simply append to that variable:

vlc_modules += {
'name' : 'file_logger',
'sources' : files('file.c')
}
Warning
Make sure to not accidentally overwrite the vlc_modules variable by using an = instead of += when appending the dictionary.

Currently the modules dict accepts the following keys:

Parameters
nameThe name of the VLC plugin (used for the MODULE_STRING define). Required
sourcesThe source files for the module, use files() to specify them. Required
enabledA boolean indicating whether the module should be built or not.
dependenciesThe dependencies needed by the module. Only list external dependencies here, not libraries that are built as part of the VLC build, for these use link_with instead.
include_directoriesAdditional include directories that should be used when compiling the module. These should be specified using the include_directories() function.
c_argsAdditional flags to pass to the C compiler.
cpp_argsAdditional flags to pass to the C++ compiler.
objc_argsAdditional flags to pass to the Objective-C compiler.
link_argsAdditional flags to pass to the dynamic linker. Do not use this to specify additional libraries to link with, use the dependencies instead.
link_languageForce the linker to be for the specified language. This is not needed in most cases but can be useful for example for a C plugin that depends on a C++ library therefore needing the C++ standard library linked.

Checking the host system

It is frequently necessary to check the host we are building for. To do that, use the host_system variable. For possible values, refer to the reference table in the documentation.

For now, host_system is equivalent to host_machine.system(), however this might not always be the case, hence the special variable for that.

Finding dependencies

As most VLC modules likely require an external dependency too, let's have a look how to find a dependency and add an option for it.

To find dependencies, Meson has essentially two options:

Generally the latter should be preferred in most cases. It primarily uses pkg-config to find the dependency, however even for very common dependencies that do not provide a .pc file, it can have handling to find it by other means. For a full list of the special cases, consult the documentation. It is roughly equivalent to PKG_CHECK_MODULES in autoconf.

However there might be a case where you need to find a library that has no .pc file, no custom *-config tool or handling by meson. In these cases you can use the compiler object's find_library function. It basically does a linker check for the specified library name and returns a dependency object for it. It is roughtly equivalent to AC_CHECK_LIB in autoconf.

Options

To add an option for the dependency, add the respective option entry in meson_options.txt:

option('dav1d',
type : 'feature',
value : 'auto',
description : 'libdav1d AV1 decoder support')

This adds a new feature option with the name dav1d. A feature option is a special tri-state option that can be enabled, disabled or auto.

Now we can just look up the option and use that for the required argument of the dependency() function:

# dav1d AV1 decoder
dav1d_dep = dependency('dav1d', version: '>= 0.5.0', required: get_option('dav1d'))
vlc_modules += {
'name' : 'dav1d',
'sources' : files('dav1d.c'),
'dependencies' : [dav1d_dep],
'enabled' : dav1d_dep.found(),
}

As the option defaults to auto, meson will look it up, and if its is found, add the module. If the option is manually set to disabled, meson will never look it up and just always return a not-found dependency object. If it's set to enabled, meson will error out if it's not found.

The feature option object provides a few more useful functions, for more complex cases of conditional dependencies. For example suppose we want an option to be disabled in some cases when it is set to auto:

vlc_modules += {
'name' : 'xcb',
'sources' : files('xcb.c'),
'enabled' : get_option('x11') \
.disable_auto_if(host_system in ['darwin', 'windows']) \
.allowed(),
}

This will disable the x11 option if it is set to auto, when on darwin or windows.

Note
Options, like most objects in meson, are immutable. So if you were to instead write
x11_opt = get_option('x11')
x11_opt.disable_auto_if(host_system in ['darwin', 'windows']) # Wrong, don't do this!
if (x11_opt.allowed())
# This is not disabled on Darwin or Windows!
endif
it would not do what you might expect, as disable_auto_if returns a new option and does not mutate the existing one. The returned option object is never assigned to any variable, so it is lost.

Adding new tests

VLC tests are also meson dictionaries added to the special array named vlc_tests. This mechanism allows a test to reference modules that should be available when running the test.

To add a new test, simply append to that variable:

vlc_tests += {
'name' : 'test_src_input_thumbnail',
'sources' : files('input/thumbnail.c'),
'suite' : ['src', 'test_src'],
'link_with' : [libvlc, libvlccore],
'module_depends' : ['demux_mock', 'rawvideo']
}
Warning
Make sure to not accidentally overwrite the vlc_tests variable by using an = instead of += when appending the dictionary.

Currently the modules dictionary accepts the following keys:

Parameters
nameThe name of the new VLC test, which will map to the executable name. Required
sourcesThe source files for the new test, use files() to specify them. Required
suiteThe meson test suites to which this test should be available.
dependenciesThe dependencies needed by the test. Only list external dependencies here, not libraries that are built as part of the VLC build, for these use link_with instead.
link_withThe dependencies needed by the test that are part of the VLC build. For external dependencies, use dependencies instead.
include_directoriesAdditional include directories that should be used when compiling the test. These should be specified using the include_directories() function.
module_dependsThe list of module names this test depends upon.
moc_headersA list of header files that should be transformed by Qt's moc source translater built for the test.
c_argsAdditional flags to pass to the C compiler.
cpp_argsAdditional flags to pass to the C++ compiler.
objc_argsAdditional flags to pass to the Objective-C compiler.

To run a specific test, you can directly use:

meson test -C build-meson test_src_input_thumbnail

where test_src_input_thumbnail can be replaced by the name of the test. Make sure that a module really depends upon the module it's using through the module_depends variable. If every modules should be used to run the test, you can use the special value vlc_plugins_targets.keys(), but adding more module dependencies than necessary will drastically increase the compile time when running a specific test in cases like automated git bisect.

Compiling with contribs

The meson build system also supports using dependencies and binaries provided by the contrib system.

Once the contrib has been prepared, a meson machine file will be generated in the installation prefix. For native linux x86_64, it will typically be found at the following location:

vlc/contrib/x86_64-pc-linux-gnu/share/meson/native/contrib.ini

Then you can setup meson with this file using the following command:

meson setup build-meson \
    --native-file contrib/x86_64-pc-linux-gnu/share/meson/native/contrib.ini 

When cross-compiling, both the crossfile and the contrib machine file can be supplied at the same time:

meson setup build-meson --cross-file win32.crossfile \
    --cross-file contrib/x86_64-w64-mingw32/share/meson/cross/contrib.ini