[libcamera-devel,v1.1,02/11] libcamera: utils: Add a function to retrieve the libcamera source tree

Message ID 20200427121834.15930-1-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Untitled series #835
Related show

Commit Message

Laurent Pinchart April 27, 2020, 12:18 p.m. UTC
Similarly to libcameraBuildPath(), there's a need to locate resources
within the source tree when running libcamera without installing it.
Support this use case with a new utils::libcameraSourcePath() function.

The implementation uses a symlink from the build root to the source root
in order to avoid hardcoding the path to the source root in the
libcamera.so binary.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
Changes since v1:

- Use a symlink to the source tree to avoid hardcoding the path in the
  libcamera.so binary
---
 meson.build                   |  6 +++++
 src/libcamera/include/utils.h |  1 +
 src/libcamera/utils.cpp       | 49 ++++++++++++++++++++++++++++++++---
 3 files changed, 53 insertions(+), 3 deletions(-)

Comments

Kieran Bingham April 27, 2020, 12:26 p.m. UTC | #1
Hi Laurent,

On 27/04/2020 13:18, Laurent Pinchart wrote:
> Similarly to libcameraBuildPath(), there's a need to locate resources
> within the source tree when running libcamera without installing it.
> Support this use case with a new utils::libcameraSourcePath() function.
> 
> The implementation uses a symlink from the build root to the source root
> in order to avoid hardcoding the path to the source root in the
> libcamera.so binary.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Nice, I like this much more ;-)

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>


> ---
> Changes since v1:
> 
> - Use a symlink to the source tree to avoid hardcoding the path in the
>   libcamera.so binary
> ---
>  meson.build                   |  6 +++++
>  src/libcamera/include/utils.h |  1 +
>  src/libcamera/utils.cpp       | 49 ++++++++++++++++++++++++++++++++---
>  3 files changed, 53 insertions(+), 3 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index c6e6a934e54e..ec5bc970f5b6 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -93,6 +93,12 @@ if get_option('test')
>      subdir('test')
>  endif
>  
> +# Create a symlink from the build root to the source root. This is used when
> +# running libcamera from the build directory to locate resources in the source
> +# directory (such as IPA configuration files).
> +run_command('ln', '-fs', meson.source_root(),
> +            join_paths(meson.build_root(), 'source'))
> +

Is this run on every build? or just the first?

It's a fairly 'cheap' command so it likely doesn't matter if it's run
everytime...



>  configure_file(output : 'config.h', configuration : config_h)
>  
>  pkg_mod = import('pkgconfig')
> diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
> index 242eeded9d50..3334ff16613d 100644
> --- a/src/libcamera/include/utils.h
> +++ b/src/libcamera/include/utils.h
> @@ -188,6 +188,7 @@ private:
>  details::StringSplitter split(const std::string &str, const std::string &delim);
>  
>  std::string libcameraBuildPath();
> +std::string libcameraSourcePath();
>  
>  } /* namespace utils */
>  
> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
> index 97f9b632e45b..a96ca7f40cbd 100644
> --- a/src/libcamera/utils.cpp
> +++ b/src/libcamera/utils.cpp
> @@ -10,10 +10,13 @@
>  #include <dlfcn.h>
>  #include <elf.h>
>  #include <iomanip>
> +#include <limits.h>
>  #include <link.h>
>  #include <sstream>
>  #include <stdlib.h>
>  #include <string.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
>  #include <unistd.h>
>  
>  /**
> @@ -360,9 +363,10 @@ bool isLibcameraInstalled()
>   *
>   * During development, it is useful to run libcamera binaries directly from the
>   * build directory without installing them. This function helps components that
> - * need to locate resources, such as IPA modules or IPA proxy workers, by
> - * providing them with the path to the root of the build directory. Callers can
> - * then use it to complement or override searches in system-wide directories.
> + * need to locate resources in the build tree, such as IPA modules or IPA proxy
> + * workers, by providing them with the path to the root of the build directory.
> + * Callers can then use it to complement or override searches in system-wide
> + * directories.
>   *
>   * If libcamera has been installed, the build directory path is not available
>   * and this function returns an empty string.
> @@ -385,6 +389,45 @@ std::string libcameraBuildPath()
>  	return dirname(info.dli_fname) + "/../../";
>  }
>  
> +/**
> + * \brief Retrieve the path to the source directory
> + *
> + * During development, it is useful to run libcamera binaries directly from the
> + * build directory without installing them. This function helps components that
> + * need to locate resources in the source tree, such as IPA configuration
> + * files, by providing them with the path to the root of the source directory.
> + * Callers can then use it to complement or override searches in system-wide
> + * directories.
> + *
> + * If libcamera has been installed, the source directory path is not available
> + * and this function returns an empty string.
> + *
> + * \return The path to the source directory if running from a build directory,
> + * or an empty string otherwise
> + */
> +std::string libcameraSourcePath()
> +{
> +	std::string path = libcameraBuildPath();
> +	if (path.empty())
> +		return std::string();
> +
> +	path += "source";
> +
> +	char *real = realpath(path.c_str(), nullptr);
> +	if (!real)
> +		return std::string();
> +
> +	path = real;
> +	free(real);
> +
> +	struct stat statbuf;
> +	int ret = stat(path.c_str(), &statbuf);
> +	if (ret < 0 || (statbuf.st_mode & S_IFMT) != S_IFDIR)
> +		return std::string();
> +
> +	return path + "/";
> +}
> +
>  } /* namespace utils */
>  
>  } /* namespace libcamera */
>
Laurent Pinchart April 27, 2020, 12:35 p.m. UTC | #2
Hi Kieran,

On Mon, Apr 27, 2020 at 01:26:10PM +0100, Kieran Bingham wrote:
> On 27/04/2020 13:18, Laurent Pinchart wrote:
> > Similarly to libcameraBuildPath(), there's a need to locate resources
> > within the source tree when running libcamera without installing it.
> > Support this use case with a new utils::libcameraSourcePath() function.
> > 
> > The implementation uses a symlink from the build root to the source root
> > in order to avoid hardcoding the path to the source root in the
> > libcamera.so binary.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> Nice, I like this much more ;-)

So do I :-)

> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> > ---
> > Changes since v1:
> > 
> > - Use a symlink to the source tree to avoid hardcoding the path in the
> >   libcamera.so binary
> > ---
> >  meson.build                   |  6 +++++
> >  src/libcamera/include/utils.h |  1 +
> >  src/libcamera/utils.cpp       | 49 ++++++++++++++++++++++++++++++++---
> >  3 files changed, 53 insertions(+), 3 deletions(-)
> > 
> > diff --git a/meson.build b/meson.build
> > index c6e6a934e54e..ec5bc970f5b6 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -93,6 +93,12 @@ if get_option('test')
> >      subdir('test')
> >  endif
> >  
> > +# Create a symlink from the build root to the source root. This is used when
> > +# running libcamera from the build directory to locate resources in the source
> > +# directory (such as IPA configuration files).
> > +run_command('ln', '-fs', meson.source_root(),
> > +            join_paths(meson.build_root(), 'source'))
> > +
> 
> Is this run on every build? or just the first?
> 
> It's a fairly 'cheap' command so it likely doesn't matter if it's run
> everytime...

It's run every time meson is run, but not every time ninja is run.

> >  configure_file(output : 'config.h', configuration : config_h)
> >  
> >  pkg_mod = import('pkgconfig')
> > diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
> > index 242eeded9d50..3334ff16613d 100644
> > --- a/src/libcamera/include/utils.h
> > +++ b/src/libcamera/include/utils.h
> > @@ -188,6 +188,7 @@ private:
> >  details::StringSplitter split(const std::string &str, const std::string &delim);
> >  
> >  std::string libcameraBuildPath();
> > +std::string libcameraSourcePath();
> >  
> >  } /* namespace utils */
> >  
> > diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
> > index 97f9b632e45b..a96ca7f40cbd 100644
> > --- a/src/libcamera/utils.cpp
> > +++ b/src/libcamera/utils.cpp
> > @@ -10,10 +10,13 @@
> >  #include <dlfcn.h>
> >  #include <elf.h>
> >  #include <iomanip>
> > +#include <limits.h>
> >  #include <link.h>
> >  #include <sstream>
> >  #include <stdlib.h>
> >  #include <string.h>
> > +#include <sys/stat.h>
> > +#include <sys/types.h>
> >  #include <unistd.h>
> >  
> >  /**
> > @@ -360,9 +363,10 @@ bool isLibcameraInstalled()
> >   *
> >   * During development, it is useful to run libcamera binaries directly from the
> >   * build directory without installing them. This function helps components that
> > - * need to locate resources, such as IPA modules or IPA proxy workers, by
> > - * providing them with the path to the root of the build directory. Callers can
> > - * then use it to complement or override searches in system-wide directories.
> > + * need to locate resources in the build tree, such as IPA modules or IPA proxy
> > + * workers, by providing them with the path to the root of the build directory.
> > + * Callers can then use it to complement or override searches in system-wide
> > + * directories.
> >   *
> >   * If libcamera has been installed, the build directory path is not available
> >   * and this function returns an empty string.
> > @@ -385,6 +389,45 @@ std::string libcameraBuildPath()
> >  	return dirname(info.dli_fname) + "/../../";
> >  }
> >  
> > +/**
> > + * \brief Retrieve the path to the source directory
> > + *
> > + * During development, it is useful to run libcamera binaries directly from the
> > + * build directory without installing them. This function helps components that
> > + * need to locate resources in the source tree, such as IPA configuration
> > + * files, by providing them with the path to the root of the source directory.
> > + * Callers can then use it to complement or override searches in system-wide
> > + * directories.
> > + *
> > + * If libcamera has been installed, the source directory path is not available
> > + * and this function returns an empty string.
> > + *
> > + * \return The path to the source directory if running from a build directory,
> > + * or an empty string otherwise
> > + */
> > +std::string libcameraSourcePath()
> > +{
> > +	std::string path = libcameraBuildPath();
> > +	if (path.empty())
> > +		return std::string();
> > +
> > +	path += "source";
> > +
> > +	char *real = realpath(path.c_str(), nullptr);
> > +	if (!real)
> > +		return std::string();
> > +
> > +	path = real;
> > +	free(real);
> > +
> > +	struct stat statbuf;
> > +	int ret = stat(path.c_str(), &statbuf);
> > +	if (ret < 0 || (statbuf.st_mode & S_IFMT) != S_IFDIR)
> > +		return std::string();
> > +
> > +	return path + "/";
> > +}
> > +
> >  } /* namespace utils */
> >  
> >  } /* namespace libcamera */

Patch

diff --git a/meson.build b/meson.build
index c6e6a934e54e..ec5bc970f5b6 100644
--- a/meson.build
+++ b/meson.build
@@ -93,6 +93,12 @@  if get_option('test')
     subdir('test')
 endif
 
+# Create a symlink from the build root to the source root. This is used when
+# running libcamera from the build directory to locate resources in the source
+# directory (such as IPA configuration files).
+run_command('ln', '-fs', meson.source_root(),
+            join_paths(meson.build_root(), 'source'))
+
 configure_file(output : 'config.h', configuration : config_h)
 
 pkg_mod = import('pkgconfig')
diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
index 242eeded9d50..3334ff16613d 100644
--- a/src/libcamera/include/utils.h
+++ b/src/libcamera/include/utils.h
@@ -188,6 +188,7 @@  private:
 details::StringSplitter split(const std::string &str, const std::string &delim);
 
 std::string libcameraBuildPath();
+std::string libcameraSourcePath();
 
 } /* namespace utils */
 
diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
index 97f9b632e45b..a96ca7f40cbd 100644
--- a/src/libcamera/utils.cpp
+++ b/src/libcamera/utils.cpp
@@ -10,10 +10,13 @@ 
 #include <dlfcn.h>
 #include <elf.h>
 #include <iomanip>
+#include <limits.h>
 #include <link.h>
 #include <sstream>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 /**
@@ -360,9 +363,10 @@  bool isLibcameraInstalled()
  *
  * During development, it is useful to run libcamera binaries directly from the
  * build directory without installing them. This function helps components that
- * need to locate resources, such as IPA modules or IPA proxy workers, by
- * providing them with the path to the root of the build directory. Callers can
- * then use it to complement or override searches in system-wide directories.
+ * need to locate resources in the build tree, such as IPA modules or IPA proxy
+ * workers, by providing them with the path to the root of the build directory.
+ * Callers can then use it to complement or override searches in system-wide
+ * directories.
  *
  * If libcamera has been installed, the build directory path is not available
  * and this function returns an empty string.
@@ -385,6 +389,45 @@  std::string libcameraBuildPath()
 	return dirname(info.dli_fname) + "/../../";
 }
 
+/**
+ * \brief Retrieve the path to the source directory
+ *
+ * During development, it is useful to run libcamera binaries directly from the
+ * build directory without installing them. This function helps components that
+ * need to locate resources in the source tree, such as IPA configuration
+ * files, by providing them with the path to the root of the source directory.
+ * Callers can then use it to complement or override searches in system-wide
+ * directories.
+ *
+ * If libcamera has been installed, the source directory path is not available
+ * and this function returns an empty string.
+ *
+ * \return The path to the source directory if running from a build directory,
+ * or an empty string otherwise
+ */
+std::string libcameraSourcePath()
+{
+	std::string path = libcameraBuildPath();
+	if (path.empty())
+		return std::string();
+
+	path += "source";
+
+	char *real = realpath(path.c_str(), nullptr);
+	if (!real)
+		return std::string();
+
+	path = real;
+	free(real);
+
+	struct stat statbuf;
+	int ret = stat(path.c_str(), &statbuf);
+	if (ret < 0 || (statbuf.st_mode & S_IFMT) != S_IFDIR)
+		return std::string();
+
+	return path + "/";
+}
+
 } /* namespace utils */
 
 } /* namespace libcamera */