I've just implemented generation of pkgconfig modules into the cmake build
in r1934881 and there are few things that I believe we currently do wrong
(even in configure).

For the reference, here is what it looks like right now (with configure):

[[[
$ ./autogen.sh ; ./configure
$ cat subversion/libsvn_subr/libsvn_subr.pc
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libsvn_subr
Description: Subversion General Utility Library
Version: 1.16.0
Requires: apr-util-1, apr-1
Requires.private: sqlite3
Libs: -L${libdir}  -lsvn_subr-1 -lexpat -lz  -lmagic  -llz4 -lutf8proc
Cflags: -I${includedir}/subversion-1
$ cat subversion/libsvn_ra_serf/libsvn_ra_serf.pc
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libsvn_ra_serf
Description: Subversion HTTP/WebDAV Protocol Repository Access Library
Version: 1.16.0
Requires: apr-util-1, apr-1
Requires.private: libsvn_delta, libsvn_subr, serf-1
Libs: -L${libdir}  -lsvn_ra_serf-1 -lz
Cflags: -I${includedir}/subversion-1
]]]

First of all, why do we list dependencies in the 'Libs' field? Shouldn't it
be 'Requires.private'?

The difference between those is that libs is only flags to pass to the
linker while require[.private] are lists of other pkg-config packages to
link with. Technically, if we had a dependency that does not provide
pkg-config modules it would go there. But as far as I know, all
dependencies that we have do in fact have it, at least the mandatory ones.
Usually, Libs should only link the library itself, not the dependencies.
Cflags is *only* lib's include flags/compiler flags. Everything external
should go to Requires.

I also noticed that some dependencies are indeed listed as pkg-config
modules instead of plain flags. Those include sqlite3, serf, apr, and
other libsvn's.

Please correct me if I'm wrong, but couldn't we just use those or there
were reasons not to?

Next, I factored out code that was generating libsvn_name.pc.in files from
gen_make.py into gen_pkgconfig.py so it can be called for both, cmake and
make builds. What I was also thinking is don't we have this part a bit
overcomplicated? A python script that creates ~10 files with ~10 lines each
from a configuration file utilising a huge framework that builds an entire
dependency tree. Is it really worth it? You could take a look at the code
that does that, and to be honest it's really hard to tell what's going on
over there. After which we generate those files once again during each
configuration but substituting the template variables (though this is
common practice with pkg-config so things like install prefix could be
filled in with the correct ones).

I think it would be a lot easier to hand write those templates (
libsvn_name.pc.in) and put them into the repository. Otherwise, it might be
complicated to maintain them when it's a result of several thousands of
confusing python code buried in the depths of the source tree that nobody
could really understand...

On the good side, cmake now generates them anyways. I've tested it with a
separate program and confirmed that it works properly. Below is the cmake
script I used if anyone wants to replicate my tests (you'd also need to
nuke the system's installation of libsvn and install a dev version there.
Or I guess there is also an environment variable to change where it looks
for .pc files):

[[[
cmake_minimum_required(VERSION 3.12)
project(test)
find_package(PkgConfig)
add_executable(test test.c)
pkg_check_modules(libsvn_subr IMPORTED_TARGET libsvn_subr)
target_link_libraries(test PRIVATE PkgConfig::libsvn_subr)
]]]

There is a minor difference in what cmake produces because of the way the
link flags are retrieved, which it also prepends the full directory path of
that object. But it should be just fine and the compiler understands that.
Again, if we decide to use those libraries as Requires.private, this part
won't matter.

-- 
Timofei Zhakov

Reply via email to