From patchwork Wed Jul 3 08:00:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1589 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 86C5461571 for ; Wed, 3 Jul 2019 10:00:25 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1B29724B; Wed, 3 Jul 2019 10:00:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140825; bh=GiboB/+QpkhPSmGFFg6QBKda2DvHAu7MkYk3Dk9gck4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OXaQMmgObPqSnD9irTYcpYbAEsHYCBOVnluF1EhZb/JqgoQ3NuLBmrqg5gBkV3O/k 8lV6cyJNN03Q+hUDbs3fGG94dqE+47oE9JPGoksWxXhvbw+4byUtSpUPjC2jfw3Hrp y2TrbSaxMtTuigTkgThddYX4yEhiUB1UXnB29LOc= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:01 +0900 Message-Id: <20190703080007.21376-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 1/7] libcamera: ipa_module_info: add license field X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:25 -0000 Add a field to IPAModuleInfo to contain the license of the module. Update the dummy IPA and IPA test to conform to the new struct layout Signed-off-by: Paul Elder --- New patch in v2 - this replaces the isolate flag that was used in v1 include/libcamera/ipa/ipa_module_info.h | 2 ++ src/ipa/ipa_dummy.cpp | 1 + src/libcamera/ipa_module.cpp | 3 +++ test/ipa/ipa_test.cpp | 1 + 4 files changed, 7 insertions(+) diff --git a/include/libcamera/ipa/ipa_module_info.h b/include/libcamera/ipa/ipa_module_info.h index 585f753..39dca1a 100644 --- a/include/libcamera/ipa/ipa_module_info.h +++ b/include/libcamera/ipa/ipa_module_info.h @@ -18,6 +18,8 @@ struct IPAModuleInfo { uint32_t pipelineVersion; char pipelineName[256]; char name[256]; + char license[64]; + } __attribute__((packed)); extern "C" { diff --git a/src/ipa/ipa_dummy.cpp b/src/ipa/ipa_dummy.cpp index ee7a3a8..2e6ff71 100644 --- a/src/ipa/ipa_dummy.cpp +++ b/src/ipa/ipa_dummy.cpp @@ -34,6 +34,7 @@ const struct IPAModuleInfo ipaModuleInfo = { 0, "PipelineHandlerVimc", "Dummy IPA for Vimc", + "LGPLv2.1", }; IPAInterface *ipaCreate() diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp index d82ac69..f786c16 100644 --- a/src/libcamera/ipa_module.cpp +++ b/src/libcamera/ipa_module.cpp @@ -215,6 +215,9 @@ elfLoadSymbol(void *map, size_t soSize, const char *symbol) * * \var IPAModuleInfo::name * \brief The name of the IPA module + * + * \var IPAModuleInfo::license + * \brief License of the IPA module */ /** diff --git a/test/ipa/ipa_test.cpp b/test/ipa/ipa_test.cpp index bbef069..4c51034 100644 --- a/test/ipa/ipa_test.cpp +++ b/test/ipa/ipa_test.cpp @@ -59,6 +59,7 @@ protected: 0, "PipelineHandlerVimc", "Dummy IPA for Vimc", + "LGPLv2.1" }; count += runTest("src/ipa/ipa_dummy.so", testInfo); From patchwork Wed Jul 3 08:00:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1590 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A317061571 for ; Wed, 3 Jul 2019 10:00:27 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E92C32F0; Wed, 3 Jul 2019 10:00:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140827; bh=XM6yziVBkZ7Pax3Ys1Ef0sjD9obSjnwdVsQ3d7DkznU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RohyaIp1jWZCHniU6MKgjVi9mtOYilE4vZ22sOh98OLucDIOSBfcxEqemrvOR0CEj U+dQHsAoRm16TixSzeU1TjFfxBHF6LBkOX6IeP1rTBkO+XJMISkbSJUwYdyupygrGB usS3CLki3DbdMUVxW5pWb5VcnnwdPJFry2vLx7as= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:02 +0900 Message-Id: <20190703080007.21376-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 2/7] libcamera: process, process manager: create process and manager classes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:27 -0000 Add a Process class to abstract a process, and a ProcessManager singleton to monitor and manage the processes. Signed-off-by: Paul Elder --- New in v2 src/libcamera/include/process.h | 35 ++++++ src/libcamera/include/process_manager.h | 40 +++++++ src/libcamera/meson.build | 4 + src/libcamera/process.cpp | 140 ++++++++++++++++++++++++ src/libcamera/process_manager.cpp | 104 ++++++++++++++++++ 5 files changed, 323 insertions(+) create mode 100644 src/libcamera/include/process.h create mode 100644 src/libcamera/include/process_manager.h create mode 100644 src/libcamera/process.cpp create mode 100644 src/libcamera/process_manager.cpp diff --git a/src/libcamera/include/process.h b/src/libcamera/include/process.h new file mode 100644 index 0000000..85c0163 --- /dev/null +++ b/src/libcamera/include/process.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * process.h - Process object + */ +#ifndef __LIBCAMERA_PROCESS_H__ +#define __LIBCAMERA_PROCESS_H__ + +#include +#include + +namespace libcamera { + +class Process +{ +public: + Process(); + virtual ~Process(); + + int exec(const std::string &path, const std::vector &args, const std::vector &fds); + +private: + pid_t pid_; + bool execed_; + + /* TODO better prototype, and implementation; emit finished signal */ + virtual void sigchldHandler() { }; + + friend class ProcessManager; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_PROCESS_H__ */ diff --git a/src/libcamera/include/process_manager.h b/src/libcamera/include/process_manager.h new file mode 100644 index 0000000..9b4bf25 --- /dev/null +++ b/src/libcamera/include/process_manager.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * process_manager.h - Process manager + */ +#ifndef __LIBCAMERA_PROCESS_MANAGER_H__ +#define __LIBCAMERA_PROCESS_MANAGER_H__ + +#include "process.h" + +#include +#include + +namespace libcamera { + +class EventNotifier; + +class ProcessManager +{ +public: + int registerProcess(Process *proc); + + static ProcessManager *instance(); + +private: + std::vector processes_; + + ProcessManager(); + ~ProcessManager(); + void sigchldHandler(int sig); + + int signalfd_; + + EventNotifier *fdEvent_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_PROCESS_MANAGER_H__ */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 8075b1f..087b578 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -20,6 +20,8 @@ libcamera_sources = files([ 'media_object.cpp', 'object.cpp', 'pipeline_handler.cpp', + 'process.cpp', + 'process_manager.cpp', 'request.cpp', 'signal.cpp', 'stream.cpp', @@ -45,6 +47,8 @@ libcamera_headers = files([ 'include/media_device.h', 'include/media_object.h', 'include/pipeline_handler.h', + 'include/process.h', + 'include/process_manager.h', 'include/utils.h', 'include/v4l2_device.h', 'include/v4l2_subdevice.h', diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp new file mode 100644 index 0000000..ea7b58d --- /dev/null +++ b/src/libcamera/process.cpp @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * process.cpp - Process object + */ + +#include "process.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ipa_module.h" +#include "log.h" +#include "process_manager.h" +#include "utils.h" + +/** + * \file process.h + * \brief Process object + * + * TODO add stuff here + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(Process) + +namespace { + +void closefrom_except(int from, const std::vector &fds) +{ + std::vector v(fds); + sort(v.begin(), v.end()); + + DIR *dir = opendir("/proc/self/fd"); + if (!dir) + return; + + struct dirent *ent; + while ((ent = readdir(dir)) != nullptr) { + int fd; + if (sscanf(ent->d_name, "%d", &fd) == 1 && fd >= from && + fd != dirfd(dir) && !std::binary_search(v.begin(), v.end(), fd)) + close(fd); + } + + closedir(dir); + return; +} + +} + +/** + * \class Process + * \brief Manager for processes + * + * TODO write this + */ + +Process::Process() + : pid_(-1), execed_(false) +{ +} + +Process::~Process() +{ +} + +/** + * \brief Fork and exec a process, and close fds + * \param[in] path Path to executable + * \param[in] args Arguments to pass to executable + * \param[in] fds Vector of file descriptors to keep open + * + * Fork a process, and exec the executable specified by path. Prior to + * exec'ing, but after forking, all file descriptors except for those + * specified in fds will be closed. + * + * All indexes of args will be incremented by 1 before being fed to exec(), + * so args[0] should not need to be equal to path. + * + * \return a positive socket file descriptor on successful fork, exec, and + * closing the file descriptors, or a negative error code otherwise + */ +int Process::exec(const std::string &path, const std::vector &args, const std::vector &fds) +{ + int childPid; + + if (execed_) + return 0; + + if ((childPid = fork()) == -1) { + int err = errno; + LOG(Process, Error) << "Failed to fork: " << strerror(err); + return err; + } else if (childPid) { + std::cout << "parent uid = " << getuid() << std::endl; + pid_ = childPid; + ProcessManager::instance()->registerProcess(this); + + execed_ = true; + + return 0; + } else { + int ret; + if (unshare(CLONE_NEWUSER|CLONE_NEWNET)) { + ret = -errno; + LOG(Process, Error) + << "Failed to isolate IPA: " << strerror(-ret); + exit(ret); + } + + std::cout << "child uid = " << getuid() << std::endl; + + closefrom_except(3, fds); + + const char **argv = new const char *[args.size() + 2]; + int len = args.size(); + argv[0] = path.c_str(); + for (int i = 0; i < len; i++) + argv[i+1] = args[i].c_str(); + argv[len+1] = NULL; + + execv(path.c_str(), (char **)argv); + + ret = -errno; + LOG(Process, Error) << "Failed to exec: " << strerror(-ret); + exit(ret); + } +} + +} /* namespace libcamera */ diff --git a/src/libcamera/process_manager.cpp b/src/libcamera/process_manager.cpp new file mode 100644 index 0000000..1ba0cfb --- /dev/null +++ b/src/libcamera/process_manager.cpp @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * process_manager.cpp - Process manager + */ + +#include "process_manager.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipa_module.h" +#include "log.h" +#include "utils.h" + +/** + * \file process_manager.h + * \brief Process manager + * + * TODO add stuff here + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(ProcessManager) + +/** + * \class ProcessManager + * \brief Manager for processes + * + * TODO make this nicer + */ + +void ProcessManager::sigchldHandler(int sig) +{ + /* TODO give the process the status? */ + for (Process *p : processes_) + if ((p->pid_ = waitpid(p->pid_, NULL, WNOHANG))) + p->sigchldHandler(); +} + + +/** + * \brief Register process with process manager + * \param[in] proc Process to register + * + * Add proc to the process manager to manage. + * + * \todo add things to manage + * + * \return zero on success, or negative error value + */ +int ProcessManager::registerProcess(Process *proc) +{ + processes_.push_back(proc); + + return 0; +} + +ProcessManager::ProcessManager() +{ + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + + signalfd_ = signalfd(-1, &mask, SFD_NONBLOCK); + fdEvent_ = new EventNotifier(signalfd_, EventNotifier::Read); +} + +ProcessManager::~ProcessManager() +{ + delete fdEvent_; + close(signalfd_); +} + +/** + * \brief Retrieve the Process manager instance + * + * The ProcessManager is a singleton and can't be constructed manually. This + * function shall instead be used to retrieve the single global instance of the + * manager. + * + * \return The Process manager instance + */ +ProcessManager *ProcessManager::instance() +{ + static ProcessManager processManager; + return &processManager; +} + +} /* namespace libcamera */ From patchwork Wed Jul 3 08:00:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1591 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CBFE961570 for ; Wed, 3 Jul 2019 10:00:29 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 19B3524B; Wed, 3 Jul 2019 10:00:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140829; bh=ZisJE4OplUNqbdzGv34PdSGuuMQJGsu7yatzszB5vfQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nqAKTokYHrJwfDHn0yiK1ef6AB4Sj/TYJVOSzz9MJM+/SufY292uJ6/y6LyvoeGwf HxAYMPJ2tTJza/DMTdA4hA8Y+D82pHFogycMTDyERtcPsegUT6wqYG3rLXwxMuKU7h GAEnG9yGsXwvM91We6dwoACe+ZRMS+vSwryHQVQY= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:03 +0900 Message-Id: <20190703080007.21376-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 3/7] libcamera: add IPA proxy X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:30 -0000 Add a Proxy class whose implementations will act as a proxy between a pipeline handler and an isolated IPA interface. Also add a ProxyFactory that will construct the Proxy implementations as necessary. Update Doxygen to ignore the directory where Proxy implementations will reside. Signed-off-by: Paul Elder --- New in v2 - replaces shims from v1 - build into libcamera, hence the register macro (similar to what PipelineHandler uses) - no longer builds separate .so Documentation/Doxyfile.in | 3 +- src/libcamera/include/ipa_proxy.h | 68 ++++++++++ src/libcamera/ipa_proxy.cpp | 219 ++++++++++++++++++++++++++++++ src/libcamera/meson.build | 6 + test/libtest/test.cpp | 4 + 5 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 src/libcamera/include/ipa_proxy.h create mode 100644 src/libcamera/ipa_proxy.cpp diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 9ca3224..8c24f94 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -837,7 +837,8 @@ EXCLUDE = @TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp @TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_sysfs.h \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_udev.h \ - @TOP_SRCDIR@/src/libcamera/pipeline/ + @TOP_SRCDIR@/src/libcamera/pipeline/ \ + @TOP_SRCDIR@/src/libcamera/proxy/ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/src/libcamera/include/ipa_proxy.h b/src/libcamera/include/ipa_proxy.h new file mode 100644 index 0000000..b493c1a --- /dev/null +++ b/src/libcamera/include/ipa_proxy.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_proxy.h - Image Processing Algorithm proxy + */ +#ifndef __LIBCAMERA_IPA_PROXY_H__ +#define __LIBCAMERA_IPA_PROXY_H__ + +#include + +#include + +#include "ipa_module.h" +#include "utils.h" + +namespace libcamera { + +class Proxy : public IPAInterface +{ +public: + Proxy(IPAModule *ipam); + virtual ~Proxy(); + + virtual int init() = 0; + + bool isValid() const; + +protected: + const std::string resolvePath(const std::string &file) const; + + std::unique_ptr ipa_; + + bool valid_; +}; + +class ProxyFactory +{ +public: + ProxyFactory(const char *name); + virtual ~ProxyFactory() { }; + + virtual std::unique_ptr create(IPAModule *ipam) = 0; + + const std::string &name() const { return name_; } + + static void registerType(ProxyFactory *factory); + static std::vector &factories(); + +private: + std::string name_; +}; + +#define REGISTER_IPA_PROXY(proxy) \ +class proxy##Factory final : public ProxyFactory \ +{ \ +public: \ + proxy##Factory() : ProxyFactory(#proxy) {} \ + std::unique_ptr create(IPAModule *ipam) \ + { \ + return utils::make_unique(ipam); \ + } \ +}; \ +static proxy##Factory global_##proxy##Factory; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPA_PROXY_H__ */ diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp new file mode 100644 index 0000000..8bb3622 --- /dev/null +++ b/src/libcamera/ipa_proxy.cpp @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_proxy.cpp - Image Processing Algorithm proxy + */ + +#include "ipa_proxy.h" + +#include +#include + +#include "log.h" +#include "utils.h" + +#include + +/** + * \file ipa_proxy.h + * \brief IPA Proxy + * + * TODO write this + * + * Isolate IPA into separate process. + * + * Every subclass of proxy shall be registered with libcamera using + * the REGISTER_IPA_PROXY() macro. + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(Proxy) + +/** + * \class Proxy + * \brief IPA Proxy + * + * TODO write this + * + * Isolate IPA into separate process. + */ + +/** + * \brief Construct a Proxy instance + * \param[in] ipam The IPA module to wrap around + * + * Proxy instances shall be constructed through the ProxyFactory::create() + * method implemented by the respective factories. + */ +Proxy::Proxy(IPAModule *ipam) + : valid_(false) +{ +} + +Proxy::~Proxy() +{ +} + +/** + * \brief Check if the Proxy instance is valid + * + * A Proxy instance is valid if the IPA interface is successfully created in + * isolation, and IPC is successfully set up. + * + * \return true if the the Proxy is valid, false otherwise + */ +bool Proxy::isValid() const +{ + return valid_; +} + +/** + * \brief Find a valid full path for a proxy worker for a given executable name + * \param[in] file File name of proxy worker executable + * + * A proxy worker's executable could be found in either the global installation + * directory, or in the paths specified by the environment variable + * LIBCAMERA_IPA_PROXY_PATH. This method checks the global install directory + * first, then LIBCAMERA_IPA_PROXY_PATH in order, and returns the full path to + * the proxy worker executable that is specified by file. The proxy worker + * executable must be have exec permission. + * + * \return full path to proxy worker executable, or empty string if no valid + * executable path + */ +const std::string Proxy::resolvePath(const std::string &file) const +{ + /* Try finding the exec target from the install directory first */ + std::string proxyFile = "/" + file; + std::string proxyPath = std::string(IPA_PROXY_DIR) + proxyFile; + if (!access(proxyPath.c_str(), X_OK)) + return proxyPath; + + /* No exec target in install directory; check env variable*/ + const char *execPaths = utils::secure_getenv("LIBCAMERA_IPA_PROXY_PATH"); + while (execPaths) { + const char *delim = strchrnul(execPaths, ':'); + size_t count = delim - execPaths; + + if (count) { + std::string proxyPath(execPaths, count); + proxyPath += proxyFile; + if (!access(proxyPath.c_str(), X_OK)) + return proxyPath; + } + + if (*delim == '\0') + break; + + execPaths += count + 1; + } + + return std::string(); +} + +/** + * \var Proxy::ipa_ + * \brief The IPA interface that the Proxy is isolating + */ + +/** + * \var Proxy::valid_ + * \brief Flag to indicate if the Proxy instance is valid + * + * A Proxy instance is valid if the IPA interface is successfully created in + * isolation, and IPC is successfully set up. + * + * This flag can be read via Proxy::isValid() + * + * Implementations of the Proxy class should set this flag upon successful + * construction. + */ + +/** + * \class ProxyFactory + * \brief Registration of Proxy classes and creation of instances + * + * To facilitate discovery and instantiation of Proxy classes, the + * ProxyFactory class maintains a registry of Proxy classes. Each + * Proxy subclass shall register itself using the REGISTER_IPA_PROXY() + * macro, which will create a corresponding instance of a ProxyFactory + * subclass and register it with the static list of factories. + */ + +/** + * \brief Construct a Proxy factory + * \param[in] name Name of the Proxy class + * + * Creating an instance of the factory registers is with the global list of + * factories, accessible through the factories() function. + * + * The factory \a name is used for debugging and Proxy matching purposes + * and shall be unique. + */ +ProxyFactory::ProxyFactory(const char *name) + : name_(name) +{ + registerType(this); +} + +/** + * \fn ProxyFactory::create() + * \brief Create an instance of the Proxy corresponding to the factory + * \param[in] ipam The IPA module + * + * This virtual function is implemented by the REGISTER_IPA_PROXY() macro. + * It creates a Proxy instance that isolates an IPA interface designated + * by the IPA module \a ipam. + * + * \return a pointer to a newly constructed instance of the Proxy subclass + * corresponding to the factory + */ + +/** + * \fn ProxyFactory::name() + * \brief Retrieve the factory name + * \return The factory name + */ + +/** + * \brief Add a Proxy class to the registry + * \param[in] factory Factory to use to construct the Proxy + * + * The caller is responsible to guarantee the uniqueness of the Proxy name. + */ +void ProxyFactory::registerType(ProxyFactory *factory) +{ + std::vector &factories = ProxyFactory::factories(); + + factories.push_back(factory); + + LOG(Proxy, Debug) + << "Registered proxy \"" << factory->name() << "\""; +} + +/** + * \brief Retrieve the list of all Proxy factories + * + * The static factories map is defined inside the function to ensures it gets + * initialized on first use, without any dependency on link order. + * + * \return the list of pipeline handler factories + */ +std::vector &ProxyFactory::factories() +{ + static std::vector factories; + return factories; +} + +/** + * \def REGISTER_IPA_PROXY + * \brief Register a Proxy with the Proxy factory + * \param[in] proxy Class name of Proxy derived class to register + * + * Register a proxy subclass with the factory and make it available to + * isolate IPA modules. + */ + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 087b578..412564f 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -14,6 +14,7 @@ libcamera_sources = files([ 'ipa_interface.cpp', 'ipa_manager.cpp', 'ipa_module.cpp', + 'ipa_proxy.cpp', 'ipc_unixsocket.cpp', 'log.cpp', 'media_device.cpp', @@ -42,6 +43,7 @@ libcamera_headers = files([ 'include/formats.h', 'include/ipa_manager.h', 'include/ipa_module.h', + 'include/ipa_proxy.h', 'include/ipc_unixsocket.h', 'include/log.h', 'include/media_device.h', @@ -64,6 +66,10 @@ includes = [ subdir('pipeline') +proxy_install_dir = join_paths(get_option('libdir'), 'libcamera', 'proxy') +config_h.set('IPA_PROXY_DIR', + '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"') + libudev = dependency('libudev', required : false) if libudev.found() diff --git a/test/libtest/test.cpp b/test/libtest/test.cpp index b119cf1..35aa021 100644 --- a/test/libtest/test.cpp +++ b/test/libtest/test.cpp @@ -25,6 +25,10 @@ int Test::execute() if (ret) return errno; + ret = setenv("LIBCAMERA_IPA_PROXY_PATH", "src/libcamera/proxy_worker", 1); + if (ret) + return errno; + ret = init(); if (ret) return ret; From patchwork Wed Jul 3 08:00:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1592 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A772D61570 for ; Wed, 3 Jul 2019 10:00:31 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3E49224B; Wed, 3 Jul 2019 10:00:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140831; bh=0lfv3ebIrfnTrad1gW5etS9qqRfT+3ME5te7dwLePFc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DOnHjHLo2hMaRDI9UJLAT1I4ZltjQM3H0ZRexvsMOQeKEW7+7rNwrjnihDijFE5rr vPrI2epGvz7c1RH/6Xr2gpnT0ZAX6I5KzbttzFpM3jd4FFwle2vMV49gQImtoDRmZj HQvgNFBB59h2sEiB2spu5FYYf+jbm99FKoQD5Omg= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:04 +0900 Message-Id: <20190703080007.21376-5-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 4/7] libcamera: proxy: add default linux proxy X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:31 -0000 Add a default linux proxy. Signed-off-by: Paul Elder --- New in v2 - replaces the dummy/linux default shim src/libcamera/meson.build | 7 +- src/libcamera/proxy/meson.build | 3 + src/libcamera/proxy/proxy_linux_default.cpp | 90 +++++++++++++++++++ src/libcamera/proxy_worker/meson.build | 18 ++++ .../proxy_linux_default_worker.cpp | 46 ++++++++++ 5 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/libcamera/proxy/meson.build create mode 100644 src/libcamera/proxy/proxy_linux_default.cpp create mode 100644 src/libcamera/proxy_worker/meson.build create mode 100644 src/libcamera/proxy_worker/proxy_linux_default_worker.cpp diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 412564f..e470fe7 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -65,10 +65,7 @@ includes = [ ] subdir('pipeline') - -proxy_install_dir = join_paths(get_option('libdir'), 'libcamera', 'proxy') -config_h.set('IPA_PROXY_DIR', - '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"') +subdir('proxy') libudev = dependency('libudev', required : false) @@ -103,3 +100,5 @@ libcamera = shared_library('camera', libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h], include_directories : libcamera_includes, link_with : libcamera) + +subdir('proxy_worker') diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build new file mode 100644 index 0000000..508ed5f --- /dev/null +++ b/src/libcamera/proxy/meson.build @@ -0,0 +1,3 @@ +libcamera_sources += files([ + 'proxy_linux_default.cpp', +]) diff --git a/src/libcamera/proxy/proxy_linux_default.cpp b/src/libcamera/proxy/proxy_linux_default.cpp new file mode 100644 index 0000000..1de028a --- /dev/null +++ b/src/libcamera/proxy/proxy_linux_default.cpp @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * proxy_linux_default.cpp - Default Image Processing Algorithm proxy for Linux + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ipa_module.h" +#include "ipa_proxy.h" +#include "ipc_unixsocket.h" +#include "log.h" +#include "process.h" +#include "process_manager.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(ProxyLinuxDefault) + +class ProxyLinuxDefault : public Proxy +{ +public: + ProxyLinuxDefault(IPAModule *ipam); + ~ProxyLinuxDefault(); + + int init(); + +private: + Process *proc_; + + IPCUnixSocket *socket_; +}; + +int ProxyLinuxDefault::init() +{ + std::cout << "initializing IPA via dummy proxy!" << std::endl; + + return 0; +} + +ProxyLinuxDefault::ProxyLinuxDefault(IPAModule *ipam) + : Proxy(ipam) +{ + std::cout << "initializing dummy proxy: loading IPA from " + << ipam->path() << std::endl; + + std::vector fds; + std::vector args; + args.push_back(ipam->path()); + const std::string path = resolvePath("proxy_linux_default"); + if (path.empty()) + return; + + socket_ = new IPCUnixSocket(); + int fd = socket_->create(); + if (fd < 0) + return; + args.push_back(std::to_string(fd)); + + proc_ = new Process(); + proc_->exec(path, args, fds); + + valid_ = true; + return; +} + +ProxyLinuxDefault::~ProxyLinuxDefault() +{ + if (proc_) + delete proc_; + if (socket_) + delete socket_; +} + +REGISTER_IPA_PROXY(ProxyLinuxDefault) + +}; /* namespace libcamera */ diff --git a/src/libcamera/proxy_worker/meson.build b/src/libcamera/proxy_worker/meson.build new file mode 100644 index 0000000..6f927c5 --- /dev/null +++ b/src/libcamera/proxy_worker/meson.build @@ -0,0 +1,18 @@ +ipa_proxy_sources = [ + ['proxy_linux_default', 'proxy_linux_default_worker.cpp'] +] + +proxy_install_dir = join_paths(get_option('libdir'), 'libcamera', 'proxy') + +foreach t : ipa_proxy_sources + proxy = executable(t[0], + t[1], + name_prefix : '', + include_directories : includes, + install : true, + install_dir : proxy_install_dir, + link_with : libcamera) +endforeach + +config_h.set('IPA_PROXY_DIR', + '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"') diff --git a/src/libcamera/proxy_worker/proxy_linux_default_worker.cpp b/src/libcamera/proxy_worker/proxy_linux_default_worker.cpp new file mode 100644 index 0000000..86b7689 --- /dev/null +++ b/src/libcamera/proxy_worker/proxy_linux_default_worker.cpp @@ -0,0 +1,46 @@ +#include + +#include + +#include + +#include "ipa_module.h" +#include "ipc_unixsocket.h" +#include "utils.h" + +using namespace libcamera; + +int main(int argc, char **argv) +{ + if (argc < 3) { + std::cout << "hello world! no args" << std::endl; + return 0; + } + + int fd = std::stoi(argv[2]); + std::cout << "hello world! we're starting! fd = " << fd << ", path = " << argv[1] << std::endl; + + std::unique_ptr ipam = utils::make_unique(argv[1]); + if (!ipam->isValid() || !ipam->load()) { + std::cerr << "Houston, we have a problem: IPAModule should be valid but isn't" << std::endl; + return -1; + } + + IPCUnixSocket socket; + if (socket.bind(fd) < 0) { + std::cerr << "IPC socket binding failed" << std::endl; + return -1; + } + + std::unique_ptr ipa = ipam->createInstance(); + if (!ipa) { + std::cerr << "Failed to create IPA interface" << std::endl; + return -1; + } + + std::cout << "hello world from the proxy worker!" << std::endl; + + /* TODO IPC listening loop */ + + return 0; +} From patchwork Wed Jul 3 08:00:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1593 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 61D5661570 for ; Wed, 3 Jul 2019 10:00:33 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F40C324B; Wed, 3 Jul 2019 10:00:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140833; bh=TIn9hsceUOYFRKPXrMZHZymDLRt+xe3k7EcVlqe55ZU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I4pUwMg4PCSv9xu+gnW1BiMwMIeAQ56tiuybCymtEU/pm6IqLb+k4qdfSUnpkJLhn dtc5zlPBAmaDQ8KMPbT0CYI0e+JfqduRtcGMs282VZdkX2HyJVlGJ1Cfli1vXqgwCA ikmDzTxkBvBJ78pIUknEnlFVRRQ2LJ+12BR9/zRw= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:05 +0900 Message-Id: <20190703080007.21376-6-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 5/7] libcamera: ipa_manager: use proxy X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:33 -0000 Make IPAManager isolate an IPA in a Proxy if the IPA's license is not open source, before returning the IPA to the caller. For now, only use the default Linux proxy, and only GPL and LGPL are considered open source. Signed-off-by: Paul Elder --- New in v2 - replaces adding shims - since Proxies are not external shared objects like the shims in v1 were, there is no longer a list of shims that is treated like IPAModules - instead the matching is done by searching the list of proxy factories src/libcamera/ipa_manager.cpp | 48 +++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 532b77d..60cd84d 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -14,6 +14,7 @@ #include "ipa_module.h" #include "log.h" #include "pipeline_handler.h" +#include "ipa_proxy.h" #include "utils.h" /** @@ -25,6 +26,20 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAManager) +namespace { + +bool isOpenSource(const char *license) +{ + if (!strncmp(license, "GPL", 3)) + return true; + if (!strncmp(license, "LGPL", 4)) + return true; + + return false; +} + +} /* namespace */ + /** * \class IPAManager * \brief Manager for IPA modules @@ -129,7 +144,7 @@ int IPAManager::addDir(const char *libDir) * \param[in] maxVersion Maximum acceptable version of IPA module * * \return A newly created IPA interface, or nullptr if no matching - * IPA module is found + * IPA module is found or if the IPA interface fails to initialize */ std::unique_ptr IPAManager::createIPA(PipelineHandler *pipe, uint32_t maxVersion, @@ -144,7 +159,36 @@ std::unique_ptr IPAManager::createIPA(PipelineHandler *pipe, } } - if (!m || !m->load()) + if (!m) + return nullptr; + + if (!isOpenSource(m->info().license)) { + ProxyFactory *pf = nullptr; + std::vector &factories = ProxyFactory::factories(); + + for (ProxyFactory *factory : factories) { + /* TODO: Better matching */ + if (!strcmp(factory->name().c_str(), "ProxyLinuxDefault")) { + pf = factory; + break; + } + } + + if (!pf) { + LOG(IPAManager, Error) << "Failed to get proxy factory"; + return nullptr; + } + + std::unique_ptr proxy = pf->create(m); + if (!proxy->isValid()) { + LOG(IPAManager, Error) << "Failed to load proxy"; + return nullptr; + } + + return proxy; + } + + if (!m->load()) return nullptr; return m->createInstance(); From patchwork Wed Jul 3 08:00:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1594 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 42A2961570 for ; Wed, 3 Jul 2019 10:00:35 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CD12124B; Wed, 3 Jul 2019 10:00:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140835; bh=fpmyI4nbw4r1qYce8TWvS3+SITiy4bMlsd2onnnknKQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aztI0sQKO+n786Vg86tJKGZLaLs/1pWYZIlJmTN7UjjtusKXGm9IIZEih3Fgc4Q4S 3l+O4xl2Y1yA1pGkWSERaoB3PCjShlbqGuk/61PqwncVJ8Jd8IcJLL7aIAGWOqp+R9 QcYjR5uGsg4lneboQu4+WhI7m2uE0i+tMlLCZJeo= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:06 +0900 Message-Id: <20190703080007.21376-7-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 6/7] libcamera: ipa: add dummy IPA that needs to be isolated X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:35 -0000 Add a dummy IPA that needs to be isolated. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v2: - ipaModuleInfo contains license rather than "please isolate me" src/ipa/ipa_dummy_isolate.cpp | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/ipa/ipa_dummy_isolate.cpp diff --git a/src/ipa/ipa_dummy_isolate.cpp b/src/ipa/ipa_dummy_isolate.cpp new file mode 100644 index 0000000..f546f43 --- /dev/null +++ b/src/ipa/ipa_dummy_isolate.cpp @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_dummy.cpp - Dummy Image Processing Algorithm module + */ + +#include + +#include +#include + +namespace libcamera { + +class IPADummyIsolate : public IPAInterface +{ +public: + int init(); +}; + +int IPADummyIsolate::init() +{ + std::cout << "initializing dummy IPA!" << std::endl; + return 0; +} + +/* + * External IPA module interface + */ + +extern "C" { +const struct IPAModuleInfo ipaModuleInfo = { + IPA_MODULE_API_VERSION, + 0, + "PipelineHandlerVimc", + "Dummy IPA for Vimc that needs to be isolated", + "Proprietary", +}; + +IPAInterface *ipaCreate() +{ + return new IPADummyIsolate(); +} +}; + +}; /* namespace libcamera */ From patchwork Wed Jul 3 08:00:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1595 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D9E361570 for ; Wed, 3 Jul 2019 10:00:37 +0200 (CEST) Received: from neptunite.flets-east.jp (p1871204-ipngn14001hodogaya.kanagawa.ocn.ne.jp [153.220.127.204]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A6C1D24B; Wed, 3 Jul 2019 10:00:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562140836; bh=/s3QCv5nJ2MJzAerFkSVbuaBQNVBbcdKR6KgFkXIzRE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ryw85PqL1SS3mlvQY/PMXYLLU+jsz4UOzYCMrEcNEQuc0Bqni2o7i0SLBbxPbKCg0 0ePP0kBzPuAG4f2S8CFGkna+8PuN2kuczz6cGmqho589B1UMcgElfSoCvhZ+AsEeWc 0BpnD1iZco8OBLzCd+un1XQfpmIogCSFV5boAVs4= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Jul 2019 17:00:07 +0900 Message-Id: <20190703080007.21376-8-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190703080007.21376-1-paul.elder@ideasonboard.com> References: <20190703080007.21376-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 7/7] libcamera: ipa: meson: build dummy IPA that needs isolation X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2019 08:00:37 -0000 Add the dummy IPA that needs isolation to meson. At the same time, clean up the IPA meson to facilitate adding more IPAs. Signed-off-by: Paul Elder --- Changes in v2: - make a sub install directory for IPAs, to keep them separate from the proxies - remove shim compilation src/ipa/meson.build | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/ipa/meson.build b/src/ipa/meson.build index 3c33a37..1558002 100644 --- a/src/ipa/meson.build +++ b/src/ipa/meson.build @@ -1,15 +1,18 @@ -ipa_dummy_sources = files([ - 'ipa_dummy.cpp', -]) +ipa_dummy_sources = [ + ['ipa_dummy', 'ipa_dummy.cpp'], + ['ipa_dummy_isolate', 'ipa_dummy_isolate.cpp'], +] -ipa_install_dir = join_paths(get_option('libdir'), 'libcamera') +ipa_install_dir = join_paths(get_option('libdir'), 'libcamera', 'ipa') -ipa_dummy = shared_library('ipa_dummy', - ipa_dummy_sources, - name_prefix : '', - include_directories : libcamera_includes, - install : true, - install_dir : ipa_install_dir) +foreach t : ipa_dummy_sources + ipa = shared_module(t[0], + t[1], + name_prefix : '', + include_directories : libcamera_includes, + install : true, + install_dir : ipa_install_dir) +endforeach config_h.set('IPA_MODULE_DIR', '"' + join_paths(get_option('prefix'), ipa_install_dir) + '"')