From patchwork Thu Nov 30 14:25:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19251 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E95C8C31E9 for ; Thu, 30 Nov 2023 14:25:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EBC03629D3; Thu, 30 Nov 2023 15:25:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1701354346; bh=OQvnV1gK6BNSShRThLob5xSE1uIM3pEQPeydc5K8CSM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=FuW4CMrrLe/vJ4AuTkYWilSf1OYxrii1gM69JIgxoRZXbjWJ+nYhYLIrYR1ajH2EV WZk+EZaafX/rYcYAbTgxmlcaCn0SPR4+4ULzxLxenO88E6O+58JgjYgUt17m7ky5pr tQ8BoVp5/w/3JI2E1aW/0yDD0gGUHTR979Uy+Zv/ckNUjUAWo9WJZX8vD89v4MYe4T ixqk26KMVloZN1lelsRheGeZ+DPAZdJu3Fo2kZb5NsoR+1EN5fc1ePFkZOq48AvkQ+ YpaEN6sG7Nmdznm/OZ1Lqx5zbAqJ7TQf0nrsyjENj2NQyozG0w/o2FtPbQEOes7Bl+ BrZJVu9DFngjQ== Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 75823629C2 for ; Thu, 30 Nov 2023 15:25:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="lrNs3Big"; dkim-atps=neutral Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-a06e59384b6so147040666b.1 for ; Thu, 30 Nov 2023 06:25:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1701354344; x=1701959144; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FesQa8IGx1toANo6uMQtuuDPNiO8Dh6SuN9++vhdB9g=; b=lrNs3BigT/frhWjkFKhbLeLCL5NHBtJZe4cOJqdl8YeUWirV1ibH91IiPFpkonsYM8 4/z1abr/eL2I1fct2xNKRk6LsI8OiViXGKtWmzLi6cSN0ZEgF3pLGKJwZ0sQY57hdZ28 TyoHpa8SlFZJLX/+jfURBjYXARjV64xXOWfekBqAXBoxQbPwo3059adPS3q6Q5MvOg6n bP2IsnnLTzyNHJWzKe0LGYmWdNOLzxJ5UkGkugxnJn9o0kziRWr74lEjsvaeus/dYLz2 TcgiwQvckDL9ZpWtYEi7wC0fQz4iNSx5zeK5f1rq0ZOT2vd+1bYszts+yvoLlUde+WYl Oghw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701354344; x=1701959144; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FesQa8IGx1toANo6uMQtuuDPNiO8Dh6SuN9++vhdB9g=; b=myGB2MMRc9pjaGmE/jvAFOJDJSblsqIzd9J2vIZWixwCID/Kp11zPcKRha0t9xhJn7 d2bCwyAOjK59TRAVlMs+TnZkZCBImhiHTmpBeSaakRrBxCt8HmdYVurP24+4YMJ0jM7F aT/xuoCme3ldTTA7taKLHOVOiXqFRILgFCkpONyNm/N099N6BUzQbpeXLFuXpWzdxXoJ ogTDuwlwofqq4ZPsTxgZtm7tq9DcB8fMElgeL07JDg7ubdxbGel/5vYkZexkQ3LUa/jH qkXSNOTy73eAoAoz7pMi+zQ7bBdtA3JCpZIKNOkiZt7Wqf1GOMEEkDqoSEpnEUtNf3Xa 4AVA== X-Gm-Message-State: AOJu0Yy9TXTAIh5GPbz3npESuAVcAJdNeLk7S5eJ5a7WlhiwW24lAYL1 mB8FDNG7ETc6aJwISExbjfOSjfJyPUsJ4iaH4WoNlg== X-Google-Smtp-Source: AGHT+IG3+4XhkrglrpGMu6SQeshK27oL9V3hnmJkDu4PDnJj6YqkhMRyd8wlasXPp4qkjX8Y2NErbw== X-Received: by 2002:a17:906:1e8f:b0:9ff:aeea:89a7 with SMTP id e15-20020a1709061e8f00b009ffaeea89a7mr15662990ejj.39.1701354343769; Thu, 30 Nov 2023 06:25:43 -0800 (PST) Received: from localhost.localdomain ([88.97.53.79]) by smtp.gmail.com with ESMTPSA id a5-20020a17090640c500b009e50ea0a05asm725577ejk.99.2023.11.30.06.25.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Nov 2023 06:25:43 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Nov 2023 14:25:31 +0000 Message-Id: <20231130142534.2075-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231130142534.2075-1-naush@raspberrypi.com> References: <20231130142534.2075-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/6] build: controls: Rework how controls and properties are generated X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for using separate YAML files for controls and properties generation. The mapping of vendor/pipeline handler to control file is done through the controls_map variable in include/libcamera/meson.build. This simplifies management of vendor control definitions and avoids possible merge conflicts when changing the control_ids.yaml file for core and draft controls. With this change, libcamera and draft controls and properties files are designated the 'libcamera' vendor tag. In this change, we also rename control_ids.yaml -> control_ids_core.yaml and property_ids.yaml -> property_ids_core.yaml to designate these as core libcamera controls. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Documentation/guides/pipeline-handler.rst | 8 +-- include/libcamera/meson.build | 50 +++++++++++++++---- meson.build | 2 + ...control_ids.yaml => control_ids_core.yaml} | 0 src/libcamera/meson.build | 21 ++++++-- ...operty_ids.yaml => property_ids_core.yaml} | 0 src/py/libcamera/gen-py-controls.py | 10 ++-- src/py/libcamera/meson.build | 12 ++++- utils/gen-controls.py | 14 ++++-- 9 files changed, 87 insertions(+), 30 deletions(-) rename src/libcamera/{control_ids.yaml => control_ids_core.yaml} (100%) rename src/libcamera/{property_ids.yaml => property_ids_core.yaml} (100%) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 10b9c75c2a7f..66d428a19c4f 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -587,12 +587,12 @@ immutable properties of the ``Camera`` device. The libcamera controls and properties are defined in YAML form which is processed to automatically generate documentation and interfaces. Controls are -defined by the src/libcamera/`control_ids.yaml`_ file and camera properties -are defined by src/libcamera/`properties_ids.yaml`_. +defined by the src/libcamera/`control_ids_core.yaml`_ file and camera properties +are defined by src/libcamera/`properties_ids_core.yaml`_. .. _controls framework: https://libcamera.org/api-html/controls_8h.html -.. _control_ids.yaml: https://libcamera.org/api-html/control__ids_8h.html -.. _properties_ids.yaml: https://libcamera.org/api-html/property__ids_8h.html +.. _control_ids_core.yaml: https://libcamera.org/api-html/control__ids_8h.html +.. _properties_ids_core.yaml: https://libcamera.org/api-html/property__ids_8h.html Pipeline handlers can optionally register the list of controls an application can set as well as a list of immutable camera properties. Being both diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 5fb772e6dd14..c46a4e701ac4 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -32,22 +32,54 @@ install_headers(libcamera_public_headers, libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir -# control_ids.h and property_ids.h and associated modes -control_source_files = { - 'control_ids': 'controls', - 'property_ids': 'properties', +controls_map = { + 'controls': { + 'core': 'control_ids_core.yaml', + }, + + 'properties': { + 'core': 'property_ids_core.yaml', + } } control_headers = [] +controls_files = [] +properties_files = [] + +foreach mode, entry : controls_map + files_list = [] + input_files = [] + foreach vendor, header : entry + if vendor != 'core' and vendor != 'draft' + if vendor not in pipelines + continue + endif + endif + + if header in files_list + continue + endif + + files_list += header + input_files += files('../../src/libcamera/' + header) + endforeach + + outfile = '' + if mode == 'controls' + outfile = 'control_ids.h' + controls_files += files_list + else + outfile = 'property_ids.h' + properties_files += files_list + endif -foreach header, mode : control_source_files - input_files = files('../../src/libcamera/' + header +'.yaml') - template_file = files(header + '.h.in') + template_file = files(outfile + '.in') control_headers += custom_target(header + '_h', input : input_files, - output : header + '.h', + output : outfile, command : [gen_controls, '-o', '@OUTPUT@', - '--mode', mode, '-t', template_file, '@INPUT@'], + '--mode', mode, '-t', template_file, + '@INPUT@'], install : true, install_dir : libcamera_headers_install_dir) endforeach diff --git a/meson.build b/meson.build index e9a1c7e360ce..ee57cb780149 100644 --- a/meson.build +++ b/meson.build @@ -267,6 +267,8 @@ py_mod.find_installation('python3', modules : py_modules) summary({ 'Enabled pipelines': pipelines, 'Enabled IPA modules': enabled_ipa_names, + 'Controls files': controls_files, + 'Properties files': properties_files, 'Hotplug support': libudev.found(), 'Tracing support': tracing_enabled, 'Android support': android_enabled, diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids_core.yaml similarity index 100% rename from src/libcamera/control_ids.yaml rename to src/libcamera/control_ids_core.yaml diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 05ee38daf22b..6d9902e6ffd1 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -127,12 +127,23 @@ endif control_sources = [] -foreach source, mode : control_source_files - input_files = files(source +'.yaml') - template_file = files(source + '.cpp.in') - control_sources += custom_target(source + '_cpp', +controls_mode_files = { + 'controls' : controls_files, + 'properties' : properties_files, +} + +foreach mode, input_files : controls_mode_files + input_files = files(input_files) + + if mode == 'controls' + template_file = files('control_ids.cpp.in') + else + template_file = files('property_ids.cpp.in') + endif + + control_sources += custom_target(mode + '_cpp', input : input_files, - output : source + '.cpp', + output : mode + '_ids.cpp', command : [gen_controls, '-o', '@OUTPUT@', '--mode', mode, '-t', template_file, '@INPUT@']) endforeach diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids_core.yaml similarity index 100% rename from src/libcamera/property_ids.yaml rename to src/libcamera/property_ids_core.yaml diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py index cfcfd4d16acf..8ae8d5126e39 100755 --- a/src/py/libcamera/gen-py-controls.py +++ b/src/py/libcamera/gen-py-controls.py @@ -95,7 +95,7 @@ def main(argv): help='Output file name. Defaults to standard output if not specified.') parser.add_argument('--template', '-t', type=str, required=True, help='Template file name.') - parser.add_argument('input', type=str, + parser.add_argument('input', type=str, nargs='+', help='Input file name.') args = parser.parse_args(argv[1:]) @@ -103,11 +103,11 @@ def main(argv): print(f'Invalid mode option "{args.mode}"', file=sys.stderr) return -1 - data = open(args.input, 'rb').read() - controls = {} - vendor = yaml.safe_load(data)['vendor'] - controls[vendor] = yaml.safe_load(data)['controls'] + for input in args.input: + data = open(input, 'rb').read() + vendor = yaml.safe_load(data)['vendor'] + controls[vendor] = yaml.safe_load(data)['controls'] data = generate_py(controls, args.mode) diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build index 1c3ea1843ac0..31af63ec0dc6 100644 --- a/src/py/libcamera/meson.build +++ b/src/py/libcamera/meson.build @@ -28,11 +28,15 @@ pycamera_sources = files([ # Generate controls -gen_py_controls_input_files = files('../../libcamera/control_ids.yaml') +gen_py_controls_input_files = [] gen_py_controls_template = files('py_controls_generated.cpp.in') gen_py_controls = files('gen-py-controls.py') +foreach file : controls_files + gen_py_controls_input_files += files('../../libcamera/' + file) +endforeach + pycamera_sources += custom_target('py_gen_controls', input : gen_py_controls_input_files, output : ['py_controls_generated.cpp'], @@ -41,9 +45,13 @@ pycamera_sources += custom_target('py_gen_controls', # Generate properties -gen_py_property_enums_input_files = files('../../libcamera/property_ids.yaml') +gen_py_property_enums_input_files = [] gen_py_properties_template = files('py_properties_generated.cpp.in') +foreach file : properties_files + gen_py_property_enums_input_files += files('../../libcamera/' + file) +endforeach + pycamera_sources += custom_target('py_gen_properties', input : gen_py_property_enums_input_files, output : ['py_properties_generated.cpp'], diff --git a/utils/gen-controls.py b/utils/gen-controls.py index 56e0c7ba98f2..2a633cc0aba9 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -12,6 +12,7 @@ import operator import string import sys import yaml +import os class ControlEnum(object): @@ -342,15 +343,18 @@ def main(argv): help='Output file name. Defaults to standard output if not specified.') parser.add_argument('--template', '-t', dest='template', type=str, required=True, help='Template file name.') - parser.add_argument('input', type=str, + parser.add_argument('input', type=str, nargs='+', help='Input file name.') args = parser.parse_args(argv[1:]) - data = open(args.input, 'rb').read() - vendor = yaml.safe_load(data)['vendor'] - controls = yaml.safe_load(data)['controls'] - controls = [Control(*ctrl.popitem(), vendor) for ctrl in controls] + controls = [] + for input in args.input: + with open(input, 'rb') as f: + data = f.read() + vendor = yaml.safe_load(data)['vendor'] + ctrls = yaml.safe_load(data)['controls'] + controls = controls + [Control(*ctrl.popitem(), vendor) for ctrl in ctrls] if args.template.endswith('.cpp.in'): data = generate_cpp(controls)