mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.3k stars 1.52k forks source link

How to set absolute path for meson dependency #13182

Open Sigmanificient opened 2 weeks ago

Sigmanificient commented 2 weeks ago

I am trying to compile criterion, a library that uses meson as its build system. It depends on multiple libraries include the 2 following ones:

On the meson.build file there is the following definition:

debugbreak = dependency('debugbreak')
klib = dependency('klib')

When i build the project, it do not find both dependencies:

Run-time dependency debugbreak found: NO (tried pkgconfig and cmake)
Looking for a fallback subproject for the dependency debugbreak
meson.build:141:13: ERROR: Automatic wrap-based subproject downloading is disabled

I need the build process to happen offline, thus -Dwrap_mode=nodownload is set. Here is the full option list used to build:

--prefix=$criterion_dir
--libdir=$criterion_dir/lib
--libexecdir=$criterion_dir/libexec
--bindir=$criterion_dir/bin
--sbindir=$criterion_dir/sbin
--includedir=$criterion_dir/include
--mandir=$criterion_dir/share/man
--infodir=$criterion_dir/share/info
--localedir=$criterion_dir/share/locale
-Dauto_features=enabled
-Dwrap_mode=nodownload
--buildtype=plain

Note that this 2 pieces of software are not shipped in my package manager, thus i cannot install them regularly. However, I have then available, and have their absolute path set in $deps_path.

$deps_path/
- debugbreak/
  - debugbreak.h
- klib/
  - [c and h files]

I would like to avoid editing the meson.build file from criterion, but if i need to i can do it.

Here is a list of things i have tried

Following documentation, and online resources, I gave a fair attempt at solving this problem by myself.

Hard-coding path as fallback

By changing the dependency declaration for the following, i wanted meson to to resolve the dependency with the fallback option, using a absolute path:

dependency('debugbreak', required: true, fallback: ['/.../debugbreak'])

I did not succeed. Here is the subsequent error:

meson.build:141:13: ERROR: Subproject name must not be an absolute path.

Using cc.find_libary

I tried to replace dependency by cc.find_library.

-debugbreak = dependency('debugbreak')
+debugbreak = cc.find_library('debugbreak')

-klib = dependency('klib')
+klib = cc.find_library('klib')

Then i set the LIBRARY_PATH variable to $deps_path Build did not succeed, required dependency were not resolved successfully.

Using PKG_CONFIG_PATH

I tried to set the PKG_CONFIG_PATH environment variable as follow:

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:${deps_path}"

However, the library not having associated pc files, pkg-config was not able to resolve it properly. I cannot generate then as i cant build a shared object.

I abandoned this route.

Set the path manually

Changed the meson.biuld file to add fallbacks

-debugbreak = dependency('debugbreak')
+debugbreak = dependency('debugbreak', fallback: ['debugbreak', 'debugbreak'])

-klib = dependency('klib')
+klib = dependency('klib', fallback: ['debugbreak', 'debugbreak'])

I looked in the command lib argument available and saw a -D option. Build using -Ddebugbreak=$deps_path -Dklib=$deps_path did not succeed:

meson.build:1:0: ERROR: Unknown options: "debugbreak"

I am particularly used to Makefile-based system, and I am quite confused with this first meson experience.

How can I provide an absolute path to dependencies in order to build successfully?

eli-schwartz commented 1 week ago

I need the build process to happen offline, thus -Dwrap_mode=nodownload is set.

Note that you can still build them using subprojects offline, you just have to download the subprojects the same way you download criterion itself (presumably via tarballs saved to an offline cache).

Note that this 2 pieces of software are not shipped in my package manager, thus i cannot install them regularly. However, I have then available, and have their absolute path set in $deps_path.

Meson doesn't know whether you get a dependency from a package manager or not, but given you mention the deps_path contains .c and .h files I'm guessing you didn't build and install the dependencies even by hand -- thus as far as meson is concerned you don't have them "available".

Meson won't produce build rules to compile code that isn't part of its own project (e.g. via a subproject) and I'm not aware of any Makefile based projects that do so either. The closest thing I can think of like that is the kernel Kbuild system which builds your current directory using a Makefile installed to the system.

The best solution would be if the "debugbreak" and "klib" projects provided a system install method with pkg-config files -- header-only libraries are fairly easy, klib could install a static archive if it doesn't want to commit to a shared library interface.

When you tried patching the project to use cc.find_library instead of dependency, it should have worked, if you actually had a libklib.a or libklib.so library for it to find and it would be detected by passing -lklib to GCC.

Sigmanificient commented 1 week ago

Thanks to criterion maintainer, I was able to find put this script, which runs before the build phase:

cp -r ${debugbreak} subprojects/debugbreak
cp -r ${klib} subprojects/klib

for dep in "debugbreak" "klib"; do
  local meson="$dep/meson.build"

  chmod +w subprojects/$dep
  cp subprojects/packagefiles/$meson subprojects/$meson
done
eli-schwartz commented 1 week ago

That's what I said above:

Note that you can still build them using subprojects offline, you just have to download the subprojects the same way you download criterion itself (presumably via tarballs saved to an offline cache).

Except you're using the individual files and copying them in place instead of using meson's packagecache support. Check out the meson subprojects command for ways to interact with subprojects, including downloading them in advance, or loading them from the packagecache, or applying the meson.build patch.