jim-easterbrook / python-gphoto2

Python interface to libgphoto2
GNU Lesser General Public License v3.0
357 stars 59 forks source link

Missing libgphoto2.so symbols, library is not loaded #173

Open tmandys opened 1 week ago

tmandys commented 1 week ago

I have compiled libgphoto2 to fix a bug and python-gphoto2. Compilation passed but problem is that cython binary packages does not load libghoto2.so library and complains about missing symbols. System is Bookworm on RPI.

ImportError: /home/pi/.local/lib/python3.11/site-packages/gphoto2/_context.cpython-311-aarch64-linux-gnu.so: undefined symbol: gp_context_set_status_func I have to force loading libphoto2.so to get it working

LD_PRELOAD=/home/pi/.local/lib/python3.11/site-packages/gphoto2/libgphoto2/libgphoto2.so.6 python3 -m gphoto2

There are no bindings in cpython binaries:

ldd /home/pi/.local/lib/python3.11/site-packages/gphoto2/_context.cpython-311-aarch64-linux-gnu.so 
    linux-vdso.so.1 (0x0000007f9f02f000)
    libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f9edf0000)
    /lib/ld-linux-aarch64.so.1 (0x0000007f9eff2000)

How to fix this build issue ?

jim-easterbrook commented 1 week ago

If your python-gphoto2 installation copied libgphoto2 binaries to /home/pi/.local/lib/python3.11/site-packages/gphoto2/libgphoto2/ then it should work. It might be a naming problem - Linux libraries typically have multiple names as soft links: libgphoto2.so, libgphoto2.so.6, and libgphoto2.so.6.1.0 for example. Python packages don't do soft links, so I include just one file (libgphoto2.so.6) in the package.

Do you have LD_LIBRARY_PATH set? If so, try again with it not set.

Capturing the output of pip (with a -v verbose option) when you install python-gphoto2 might be useful in working out what's going wrong.

tmandys commented 1 week ago

I do not think it is about path to libgphoto2.so but problem when building _context*.so library where is no link to libgphoto2. When I check original file there are dependencies. Something like missing "-l" params in linker. But I do not understand what part of setup.py is responsible.

pi@digie35:~/.local/lib/python3.11/site-packages/gphoto2 $ ldd _context.cpython-311-aarch64-linux-gnu.so 
    linux-vdso.so.1 (0x0000007f84d36000)
    libgphoto2.so.6 => /lib/aarch64-linux-gnu/libgphoto2.so.6 (0x0000007f84c10000)
    libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f84a60000)
    /lib/ld-linux-aarch64.so.1 (0x0000007f84cf9000)
    libgphoto2_port.so.12 => /lib/aarch64-linux-gnu/libgphoto2_port.so.12 (0x0000007f84a30000)
    libltdl.so.7 => /lib/aarch64-linux-gnu/libltdl.so.7 (0x0000007f84a00000)
    libexif.so.12 => /lib/aarch64-linux-gnu/libexif.so.12 (0x0000007f84990000)
    libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f848f0000)
tmandys commented 1 week ago

I found the issue. When pointing GPHOTO2_ROOT to source directory of libgphoto2 then the library found by pkg-config is libgphoto2.la and output is

PKG_CONFIG_PATH=~/work/filmscanner/python/contrib/libgphoto2 pkg-config --cflags --libs libgphoto2
-I/home/pi/work/filmscanner/python/contrib/libgphoto2/. -I/usr/include/gphoto2 /home/pi/work/filmscanner/python/contrib/libgphoto2/libgphoto2/libgphoto2.la -lm -lgphoto2_port -lm

So library is not passed to setuptools. The .so library is in .lib directory

PKG_CONFIG_PATH=~/work/filmscanner/python/contrib/libgphoto2/.lib pkg-config --cflags --libs libgphoto2
-I/usr/include/gphoto2 -lgphoto2 -lgphoto2_port -lm

The workaround is adding always libgphoto2 into options.

GPHOTO2_ROOT=$PWD/../libgphoto2 CC=gcc pip install --user . -vvvv

git diff setup.py
diff --git a/setup.py b/setup.py
index bc5edf9..69556ce 100644
--- a/setup.py
+++ b/setup.py
@@ -94,7 +94,12 @@ if 'GPHOTO2_ROOT' in os.environ:
     extra_link_args = ['-Wl,-rpath,$ORIGIN/libgphoto2']
     if sys.platform =='linux':
         extra_link_args += ['-Wl,--disable-new-dtags']
+        extra_link_args += ['-lgphoto2']

 cmd = ['pkg-config', '--modversion', 'libgphoto2']
 FNULL = open(os.devnull, 'w')
 try:

Note I also encountered linker non-optimization but seems it is not needed.

if sys.platform =='linux':
    extra_link_args += ['-Wl,--no-as-needed']

Note: does not work with g++.

jim-easterbrook commented 6 days ago

I suspect you are linking directly to your libgphoto2 build (in ~/work/filmscanner/python/contrib/libgphoto2 ?) which means the python-gphoto2 install will stop working if that build is removed or renamed. ldd on one of the compiled python modules should test that.

The compiler and linker options are obtained via pkg-config. Try setting PKG_CONFIG_PATH to the directory of your libgphoto2 local build libgphoto2.pc, then running pkg-config --variable=libdir libgphoto2 and pkg-config --cflags --libs libgphoto2. These should show the path to the libraries and the compile & link options needed.

tmandys commented 5 days ago

libgphoto2 was compiled out of box. Yes, issue is value returned by pkg-config. When PKG_CONFIG_PATH points to directory where are object files and static libgphoto2.la library (i.e. which is intended) then returns -lm -lgphoto2_port -lm. When pointing to directory with libgphoto2.so (which is compiled in .lib subdir) then returns -lgphoto2 -lgphoto2_port -lm. I do not know where is origin of issue but not easy to find. Adding extra_link_args += ['-lgphoto2'], note in README or raising some warning should help.

jim-easterbrook commented 5 days ago

Find the file libgphoto2.pc and paste its contents here.

tmandys commented 5 days ago

libgphoto2-2.5.31.2/libgphoto2.pc

prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib/aarch64-linux-gnu
includedir=${prefix}/include
VERSION=2.5.31.2
driverdir=${libdir}/libgphoto2/2.5.31.2

Name: libgphoto2
Description: Library for easy access to digital cameras
URL: http://gphoto.org/proj/libgphoto2/
Version: 2.5.31.2
Requires: libgphoto2_port >= 0.12.1
Requires.private: libexif >= 0.6.13
Libs: -L${libdir} -lgphoto2 -lm
Cflags: -I${includedir} -I${includedir}/gphoto2
jim-easterbrook commented 5 days ago

That's the one for a system libgphoto2 in /usr. I meant the one for your local install of libgphoto2 that python-gphoto2's setup.py will find, based on your GPHOTO2_ROOT setting. (There needs to be one, and only one, somewhere under GPHOTO2_ROOT where Python's os.walk will find it.)

tmandys commented 5 days ago

It is file in source libgphoto2 directory which is referenced by GPHOTO2_ROOT.

/home/pi/work/libgphoto2                                                         
    libgphoto2.pc                                                                                           
/home/pi/work/libgphoto2/libgphoto2-2.5.31.2                                     
    libgphoto2.pc               <------------------                                                                            
/home/pi/work/libgphoto2/l~debian/libgphoto2/usr/lib/aarch64-linux-gnu/pkgconfig 
    libgphoto2.pc                        
+
/home/pi/.local/lib/pkgconfig 
    libgphoto2.pc             

All files seems almost equal, just prefix differs

jim-easterbrook commented 5 days ago

One of them should have the prefix you used when you ran configure before building and installing libgphoto2. That is the one to use.On 30 Jun 2024 11:03, tmandys @.***> wrote: It is file in source libgphoto2 directory which is referenced by GPHOTO2_ROOT. /home/pi/work/libgphoto2
libgphoto2.pc
/home/pi/work/libgphoto2/libgphoto2-2.5.31.2
libgphoto2.pc <------------------
/home/pi/work/libgphoto2/l~debian/libgphoto2/usr/lib/aarch64-linux-gnu/pkgconfig libgphoto2.pc
+ /home/pi/.local/lib/pkgconfig libgphoto2.pc

All files seems almost equal, just prefix differs

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

tmandys commented 5 days ago

Issue is where pointing PKG_CONFIG_DIR evaluated in setup.py. This is from fresh libgphoto2 and python-gphoto2 repository clone. Seems pkg-config get Libs value from libgphoto2/libgphoto2-uninstalled.pc, not from libgphoto2/libgphoto2.pc.

pi@digie35:~/work/digie35-python/contrib/libgphoto2 $ PKG_CONFIG_PATH=/home/pi/work/digie35-python/contrib/libgphoto2 strace pkg-config --cflags --libs libgphoto2
execve("/usr/bin/pkg-config", ["pkg-config", "--cflags", "--libs", "libgphoto2"], 0x7ff52819f8 /* 52 vars */) = 0
brk(NULL)                               = 0x55940c5000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f95889000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=95679, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 95679, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f95838000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libpkgconf.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=68584, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 197776, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f95807000
mmap(0x7f95810000, 132240, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7f95810000
munmap(0x7f95807000, 36864)             = 0
munmap(0x7f95831000, 25744)             = 0
mprotect(0x7f9581e000, 65536, PROT_NONE) = 0
mmap(0x7f9582e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe000) = 0x7f9582e000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0py\2\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=1651472, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 1826976, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f95651000
mmap(0x7f95660000, 1761440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7f95660000
munmap(0x7f95651000, 61440)             = 0
munmap(0x7f9580f000, 160)               = 0
mprotect(0x7f957e7000, 86016, PROT_NONE) = 0
mmap(0x7f957fc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18c000) = 0x7f957fc000
mmap(0x7f95802000, 49312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f95802000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f95887000
set_tid_address(0x7f95887110)           = 65930
set_robust_list(0x7f95887120, 24)       = 0
rseq(0x7f95887760, 0x20, 0, 0xd428bc00) = 0
mprotect(0x7f957fc000, 16384, PROT_READ) = 0
mprotect(0x7f9582e000, 8192, PROT_READ) = 0
mprotect(0x5566c1f000, 4096, PROT_READ) = 0
mprotect(0x7f9588e000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f95838000, 95679)             = 0
getrandom("\x46\x93\x3e\x02\xf6\x74\x5b\x4e", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0x55940c5000
brk(0x55940e6000)                       = 0x55940e6000
newfstatat(AT_FDCWD, "/usr/local/lib/aarch64-linux-gnu/pkgconfig", 0x7fd92d8658, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/lib/pkgconfig", 0x7fd92d8658, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/share/pkgconfig", 0x7fd92d8658, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/usr/lib/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/usr/share/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2-uninstalled.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=1048, ...}, AT_EMPTY_PATH) = 0
read(3, "# Note: As this file is sitting "..., 4096) = 1048
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2_port-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2_port.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2_port-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2_port.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=395, ...}, AT_EMPTY_PATH) = 0
read(3, "prefix=/usr\nexec_prefix=${prefix"..., 4096) = 395
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2-uninstalled.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=1048, ...}, AT_EMPTY_PATH) = 0
read(3, "# Note: As this file is sitting "..., 4096) = 1048
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libexif-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libexif.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libexif-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libexif.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=260, ...}, AT_EMPTY_PATH) = 0
read(3, "prefix=/usr\nexec_prefix=${prefix"..., 4096) = 260
read(3, "", 4096)                       = 0
close(3)                                = 0
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x4), ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2-uninstalled.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=1048, ...}, AT_EMPTY_PATH) = 0
read(3, "# Note: As this file is sitting "..., 4096) = 1048
read(3, "", 4096)                       = 0
close(3)                                = 0
write(1, "-I/home/pi/work/digie35-python/c"..., 172-I/home/pi/work/digie35-python/contrib/libgphoto2/. -I/usr/include/gphoto2 /home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libgphoto2.la -lm -lgphoto2_port -lm 
) = 172
exit_group(0)                           = ?
+++ exited with 0 +++

/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2.pc

prefix=/home/pi/.local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
VERSION=2.5.31.2
driverdir=${libdir}/libgphoto2/2.5.31.2

Name: libgphoto2
Description: Library for easy access to digital cameras
URL: http://gphoto.org/proj/libgphoto2/
Version: 2.5.31.2
Requires: libgphoto2_port >= 0.12.1
Requires.private: libexif >= 0.6.13
Libs: -L${libdir} -lgphoto2 -lm
Cflags: -I${includedir} -I${includedir}/gphoto2

home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2-uninstalled.pc

Name: libgphoto2
Description: Library for easy access to digital cameras
URL: http://gphoto.org/proj/libgphoto2/
Version: ${VERSION}
Requires: libgphoto2_port >= 0.12.1
Requires.private: libexif >= 0.6.13
# This is what works for gphoto-suite
Libs: ${pcfiledir}/libgphoto2/libgphoto2.la -lm
Cflags: -I${pcfiledir}/.
# This is what Sun wants (and does not work with gphoto-suite)
# Libs: ${pc_top_builddir}/${pcfiledir}/libgphoto2/libgphoto2.la -lm
# Cflags: -I${pc_top_builddir}/${pcfiledir}

Working but it takes wrong .pc system file

pi@digie35:~/work/digie35-python/contrib/libgphoto2 $ PKG_CONFIG_PATH=/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2 strace pkg-config --cflags --libs libgphoto2
execve("/usr/bin/pkg-config", ["pkg-config", "--cflags", "--libs", "libgphoto2"], 0x7fd052e358 /* 52 vars */) = 0
brk(NULL)                               = 0x5566689000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7faa916000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=95679, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 95679, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7faa8c5000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libpkgconf.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=68584, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 197776, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7faa894000
mmap(0x7faa8a0000, 132240, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7faa8a0000
munmap(0x7faa894000, 49152)             = 0
munmap(0x7faa8c1000, 13456)             = 0
mprotect(0x7faa8ae000, 65536, PROT_NONE) = 0
mmap(0x7faa8be000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe000) = 0x7faa8be000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0py\2\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=1651472, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 1826976, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7faa6e1000
mmap(0x7faa6f0000, 1761440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7faa6f0000
munmap(0x7faa6e1000, 61440)             = 0
munmap(0x7faa89f000, 160)               = 0
mprotect(0x7faa877000, 86016, PROT_NONE) = 0
mmap(0x7faa88c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18c000) = 0x7faa88c000
mmap(0x7faa892000, 49312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7faa892000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7faa914000
set_tid_address(0x7faa914110)           = 65938
set_robust_list(0x7faa914120, 24)       = 0
rseq(0x7faa914760, 0x20, 0, 0xd428bc00) = 0
mprotect(0x7faa88c000, 16384, PROT_READ) = 0
mprotect(0x7faa8be000, 8192, PROT_READ) = 0
mprotect(0x555eeef000, 4096, PROT_READ) = 0
mprotect(0x7faa91b000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7faa8c5000, 95679)             = 0
getrandom("\x94\x2e\x4c\xd5\x86\xf4\x18\x78", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0x5566689000
brk(0x55666aa000)                       = 0x55666aa000
newfstatat(AT_FDCWD, "/usr/local/lib/aarch64-linux-gnu/pkgconfig", 0x7ffa7fca08, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/lib/pkgconfig", 0x7ffa7fca08, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/share/pkgconfig", 0x7ffa7fca08, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/usr/lib/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/usr/share/pkgconfig", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libgphoto2-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libgphoto2.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=437, ...}, AT_EMPTY_PATH) = 0
read(3, "prefix=/usr\nexec_prefix=${prefix"..., 4096) = 437
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libgphoto2_port-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libgphoto2_port.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2_port-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2_port.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=395, ...}, AT_EMPTY_PATH) = 0
read(3, "prefix=/usr\nexec_prefix=${prefix"..., 4096) = 395
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libexif-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2/libexif.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libexif-uninstalled.pc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/pkgconfig/libexif.pc", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=260, ...}, AT_EMPTY_PATH) = 0
read(3, "prefix=/usr\nexec_prefix=${prefix"..., 4096) = 260
read(3, "", 4096)                       = 0
close(3)                                = 0
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x4), ...}, AT_EMPTY_PATH) = 0
write(1, "-I/usr/include/gphoto2 -lgphoto2"..., 53-I/usr/include/gphoto2 -lgphoto2 -lgphoto2_port -lm 
) = 53
exit_group(0)                           = ?
+++ exited with 0 +++

less /usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2.pc

prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib/aarch64-linux-gnu
includedir=${prefix}/include
VERSION=2.5.30
driverdir=${libdir}/libgphoto2/2.5.30

Name: libgphoto2
Description: Library for easy access to digital cameras
URL: http://gphoto.org/proj/libgphoto2/
Version: 2.5.30
Requires: libgphoto2_port >= 0.12.1
Requires.private: libexif >= 0.6.13
Libs: -L${libdir} -lgphoto2 -lm
Cflags: -I${includedir} -I${includedir}/gphoto2
jim-easterbrook commented 4 days ago

I'm getting more and more confused by all this. /home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2.pc has a suitable prefix, so /home/pi/.local/lib/pkgconfig/libgphoto2.pc should exist and be used if you set GPHOTO2_ROOT to /home/pi/.local.

/usr/lib/aarch64-linux-gnu/pkgconfig/libgphoto2.pc is for the system installed libgphoto2.

tmandys commented 4 days ago

Key is this line where pkg-config is satisfied with libgphoto2-uninstalled.pc file even also libgphoto2.pc does exists in directory. I do not know what is convention with these *.pc files and what they actually define in build chain. Looks as it is static library linking definition or so.

openat(AT_FDCWD, "/home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2-uninstalled.pc", O_RDONLY) = 3

See pkg-config man page (https://linux.die.net/man/1/pkg-config)

_--uninstalled Normally if you request the package "foo" and the package "foo-uninstalled" exists, pkg-config will prefer the "-uninstalled" variant. This allows compilation/linking against uninstalled packages. If you specify the "--uninstalled" option, pkg-config will return successfully if any "-uninstalled" packages are being used, and return failure (false) otherwise. (The "PKG_CONFIG_DISABLEUNINSTALLED" environment variable keeps pkg-config from implicitly choosing "-uninstalled" packages, so if that variable is set, they will only have been used if you pass a name like "foo-uninstalled" on the command line explicitly.)

jim-easterbrook commented 4 days ago

I don't understand why setup.py would look at /home/pi/work/digie35-python/contrib/libgphoto2 if you've set GPHOTO2_ROOT to /home/pi/.local.

tmandys commented 4 days ago

I stuck with GPHOTO2_ROOT=/home/pi/work/digie35-python/contrib/libgphoto2 as the correct location. I tested all options when I was unable to get it working.

Note that I have no DEBIAN/control sources to package libgphoto2 the same way as original one. So it is handy I do not need install it as the .so library come with python-ghoto2.

jim-easterbrook commented 4 days ago

The file INSTALL.rst shows how to configure, make, and "install" libgphoto2 so that python-gphoto2 can use it. You choose your own "install" directory, so I suggest creating an empty directory, e.g. $HOME/local_libgphoto2:

$ ./configure --prefix=$HOME/local_libgphoto2
$ make
$ make install

The "install" stage copies all the files needed to use libgphoto2, including libgphoto2.pc, to subdirectories of $HOME/local_libgphoto2.

Then use this directory when installing python-gphoto2:

$ GPHOTO2_ROOT=$HOME/local_libgphoto2 pip3 install gphoto2 --user --no-binary :all:

There is no requirement for debian packaging or anything like that.

jim-easterbrook commented 4 days ago

Note that /home/pi/work/digie35-python/contrib/libgphoto2/libgphoto2.pc says the library is installed with prefix=/home/pi/.local, so if GPHOTO2_ROOT=/home/pi/work/digie35-python/contrib/libgphoto2 worked it would look for files in /home/pi/.local, just as GPHOTO2_ROOT=/home/pi/.local would.