Skip to content

Commit

Permalink
[modules] Add kconfig module
Browse files Browse the repository at this point in the history
Add a kconfig module to allow meson to integrate with existing projects
that use kconfig.
  • Loading branch information
Mark Schulte authored and bonzini committed Mar 7, 2019
1 parent df41c9a commit e6fd635
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/markdown/Kconfig-module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
short-description: Kconfig module
authors:
- name: Mark Schulte, Paolo Bonzini
years: [2017, 2019]
has-copyright: false
...

# Kconfig module

This module parses Kconfig output files to allow use of kconfig
configurations in meson projects.

**Note**: this does not provide kconfig frontend tooling to generate a
configuration. You still need something such as kconfig frontends (see
link below) to parse your Kconfig files, and then (after you've
choosen the configuration options), output a ".config" file.

[kconfig-frontends]: http://ymorin.is-a-geek.org/projects/kconfig-frontends

## Usage

To use this module, just do: **`kconfig = import('unstable-kconfig')`**.
The following functions will then be available as methods on the object
with the name `kconfig`. You can, of course, replace the name
`kconfig` with anything else.

### kconfig.load()

This function loads an output file, usually ".config", (the file path
must be specified as the first and only argument) to load a configuration
from. The configuration is returned as a dictionary object.

Note that `kconfig.load()` makes no attempt at parsing the values in the
file. Therefore, true boolean values will be represented as the string "y"
and integer values will have to be converted with `.to_int()`.

* The first (and only) argument is the path to the configuration file to
load (usually ".config").

**Returns**: a [dictionary object](Reference-manual.md#dictionary-object).
5 changes: 5 additions & 0 deletions docs/markdown/Release-notes-for-0.50.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ always be built by default.
Now if `build_by_default` is explicitly set to false it will no longer be
overridden. If `build_by_default` is not set, its default will still be
determined by the value of `install` for greater backward compatibility.

## Adding module to parse kconfig output files

Adds the ability to load and use kconfig output files as part of the
`meson.build` files be loading the kconfig module.
1 change: 1 addition & 0 deletions docs/sitemap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ index.md
Simd-module.md
Windows-module.md
Cuda-module.md
Kconfig-module.md
Java.md
Vala.md
D.md
Expand Down
72 changes: 72 additions & 0 deletions mesonbuild/modules/unstable_kconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2017, 2019 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from . import ExtensionModule

from .. import mesonlib
from ..mesonlib import typeslistify
from ..interpreterbase import FeatureNew, noKwargs
from ..interpreter import InvalidCode

import os

class KconfigModule(ExtensionModule):

@FeatureNew('Kconfig Module', '0.50.0')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.snippets.add('load')

def _load_file(self, path_to_config):
result = dict()
try:
with open(path_to_config) as f:
for line in f:
if '#' in line:
comment_idx = line.index('#')
line = line[:comment_idx]
line = line.strip()
try:
name, val = line.split('=', 1)
except ValueError:
continue
result[name.strip()] = val.strip()
except IOError as e:
raise mesonlib.MesonException('Failed to load {}: {}'.format(path_to_config, e))

return result

@noKwargs
def load(self, interpreter, state, args, kwargs):
sources = typeslistify(args, (str, mesonlib.File))
if len(sources) != 1:
raise InvalidCode('load takes only one file input.')

s = sources[0]
if isinstance(s, mesonlib.File):
# kconfig input is processed at "meson setup" time, not during
# the build, so it cannot reside in the build directory.
if s.is_built:
raise InvalidCode('kconfig input must be a source file.')
s = s.relative_name()

s = os.path.join(interpreter.environment.source_dir, s)
if s not in interpreter.build_def_files:
interpreter.build_def_files.append(s)

return self._load_file(s)


def initialize(*args, **kwargs):
return KconfigModule(*args, **kwargs)
1 change: 1 addition & 0 deletions run_project_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ def detect_tests_to_run():
('failing-meson', 'failing', False),
('failing-build', 'failing build', False),
('failing-test', 'failing test', False),
('kconfig', 'kconfig', False),

('platform-osx', 'osx', not mesonlib.is_osx()),
('platform-windows', 'windows', not mesonlib.is_windows() and not mesonlib.is_cygwin()),
Expand Down
3 changes: 3 additions & 0 deletions test cases/kconfig/1 basic/.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_VAL1=y
# CONFIG_VAL2 is not set
CONFIG_VAL_VAL=4
16 changes: 16 additions & 0 deletions test cases/kconfig/1 basic/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project('kconfig basic test')

k = import('unstable-kconfig')
conf = k.load('.config')

if not conf.has_key('CONFIG_VAL1')
error('Expected CONFIG_VAL1 to be set, but it wasn\'t')
endif

if conf.has_key('CONFIG_VAL2')
error('Expected CONFIG_VAL2 not be set, but it was')
endif

if conf.get('CONFIG_VAL_VAL').to_int() != 4
error('Expected CONFIG_VAL_VAL to be 4')
endif
2 changes: 2 additions & 0 deletions test cases/kconfig/2 subdir/.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IS_SET=y
# CONFIG_NOT_IS_SET is not set
13 changes: 13 additions & 0 deletions test cases/kconfig/2 subdir/dir/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

k = import('unstable-kconfig')

conf = k.load(meson.source_root() / '.config')

if not conf.has_key('CONFIG_IS_SET')
error('Expected CONFIG_IS_SET to be set, but it wasn\'t')
endif

if conf.has_key('CONFIG_NOT_IS_SET')
error('Expected CONFIG_NOT_IS_SET not be set, but it was')
endif

4 changes: 4 additions & 0 deletions test cases/kconfig/2 subdir/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('kconfig subdir test')

# Test into sub directory
subdir('dir')
2 changes: 2 additions & 0 deletions test cases/kconfig/3 load_config files/dir/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IS_SET=y
# CONFIG_NOT_IS_SET is not set
13 changes: 13 additions & 0 deletions test cases/kconfig/3 load_config files/dir/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

k = import('unstable-kconfig')

conf = k.load(files('config'))

if not conf.has_key('CONFIG_IS_SET')
error('Expected CONFIG_IS_SET to be set, but it wasn\'t')
endif

if conf.has_key('CONFIG_NOT_IS_SET')
error('Expected CONFIG_NOT_IS_SET not be set, but it was')
endif

4 changes: 4 additions & 0 deletions test cases/kconfig/3 load_config files/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('kconfig subdir test')

# Test into sub directory
subdir('dir')

0 comments on commit e6fd635

Please sign in to comment.