Skip to content

Commit 6ca92c3

Browse files
committed
backend: Allow local builds to use the src backend_default_config.json
If an application links to a local install of libpisp.so, the backend will fail to find backend_default_config.json in the data install path. Fix this by testing if libpisp is installed, and if not, use the build path to find backend_default_config.json, which is now copied to the specific location by the build scripts. This functionality needs linkage with libdl as well as a custom rpath that gets stripped with a meson install step. Signed-off-by: Naushir Patuck <[email protected]>
1 parent 7d49ac3 commit 6ca92c3

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

src/libpisp/backend/backend_default_config.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
*/
88
#include "backend.hpp"
99

10+
#include <dlfcn.h>
11+
#include <elf.h>
1012
#include <fstream>
13+
#include <link.h>
1114
#include <string>
1215
#include <vector>
1316

@@ -25,6 +28,40 @@ using json = nlohmann::json;
2528
namespace
2629
{
2730

31+
// Check if the RPATH or RUNPATH definitions exist in the ELF file. If they don't exist, it means that meson has
32+
// stripped them out when doing the install step.
33+
//
34+
// Source: https://stackoverflow.com/questions/2836330/is-there-a-programmatic-way-to-inspect-the-current-rpath-on-linux
35+
bool is_installed()
36+
{
37+
const ElfW(Dyn) *dyn = _DYNAMIC;
38+
for (; dyn->d_tag != DT_NULL; dyn++)
39+
{
40+
if (dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH)
41+
return false;
42+
}
43+
return true;
44+
}
45+
46+
std::string source_path()
47+
{
48+
Dl_info dl_info;
49+
std::string path;
50+
51+
if (dladdr(reinterpret_cast<void *>(source_path), &dl_info))
52+
path = dl_info.dli_fname;
53+
54+
if (path.empty())
55+
return {};
56+
57+
auto const pos = path.find_last_of('/');
58+
if (pos == std::string::npos)
59+
return {};
60+
61+
path.erase(pos, path.length() - pos);
62+
return path;
63+
}
64+
2865
void initialise_debin(pisp_be_debin_config &debin, const json &root)
2966
{
3067
constexpr unsigned int num_coefs = sizeof(debin.coeffs) / sizeof(debin.coeffs[0]);
@@ -269,8 +306,22 @@ void BackEnd::InitialiseSharpen(pisp_be_sharpen_config &sharpen, pisp_be_sh_fc_c
269306

270307
void BackEnd::initialiseDefaultConfig(const std::string &filename)
271308
{
272-
std::string file = filename.empty() ? std::string(PISP_BE_CONFIG_DIR) + "/" + "backend_default_config.json"
273-
: filename;
309+
std::string file(filename);
310+
311+
if (file.empty())
312+
{
313+
if (!is_installed())
314+
{
315+
std::string path = source_path();
316+
if (path.empty())
317+
throw std::runtime_error("BE: Could not determine the local source path");
318+
319+
file = path + "/libpisp/backend/backend_default_config.json";
320+
}
321+
else
322+
file = std::string(PISP_BE_CONFIG_DIR) + "/" + "backend_default_config.json";
323+
}
324+
274325
std::ifstream ifs(file);
275326
if (!ifs.good())
276327
throw std::runtime_error("BE: Could not find config json file: " + file);

src/libpisp/backend/meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,12 @@ install_headers(backend_headers, subdir: backend_include_dir)
2525
install_data('backend_default_config.json',
2626
install_dir : config_install_dir)
2727

28+
# Copy the json config file to the build directory for running locally.
29+
custom_target('Default config to build dir',
30+
input : 'backend_default_config.json',
31+
output : 'backend_default_config.json',
32+
command : ['cp', '@INPUT@', '@OUTPUT@'],
33+
install : false,
34+
build_by_default : true)
35+
2836
subdir('tiling')

src/meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ pisp_deps = [
1616
dependency('threads')
1717
]
1818

19+
# Meson version >= 0.64 can simply use dependency('dl') for this, but we don't want to bump up the min version just yet.
20+
dl_dep = meson.get_compiler('c').find_library('dl', required : true)
21+
pisp_deps += dl_dep
22+
1923
logging_dep = dependency('boost', modules : ['log', 'log_setup', 'thread', 'system'], required : get_option('logging'))
2024
if logging_dep.found()
2125
logging_args = ['-DPISP_LOGGING_ENABLE=1', '-DBOOST_BIND_GLOBAL_PLACEHOLDERS', '-DBOOST_LOG_DYN_LINK=1']
@@ -54,6 +58,7 @@ libpisp = library(
5458
include_directories : include_directories(inc_dirs),
5559
name_prefix : '',
5660
install : true,
61+
build_rpath : meson.project_source_root(),
5762
dependencies : pisp_deps,
5863
)
5964

0 commit comments

Comments
 (0)