conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
7.95k stars 951 forks source link

[bug] incorrect paths generated by pkgconfigdeps.py when using --deployer option #16543

Open vijay8i opened 5 days ago

vijay8i commented 5 days ago

Incorrect path generated by PkgConfigDeps when using --deployer option

OS and Connan Version Information: OS: Mac Sonama Conan version 2.4.1

How to reproduce it

  1. Create a conanfile.txt with a couple of packages; shouldn't matter what these packages are as long as they are available in the central registry; here is the file contents I used:
    
    [requires]
    libuv/1.48.0
    uvw/3.4.0

[generators] PkgConfigDeps


The important item to focus on is the use of `PkgConfigDeps`

2. The happy path (which is to use the packages from cache) works.
```bash
conan install . --output-folder=third-party --build=missing

Examine the contents of any *.pc file inside third-party folder and make note of the use of prefix and the values of libdir, includedir, ...

They are correct.

  1. The not so common or recommended path (i,e., make a copy of the dependencies locally)
# doesn't matter if its direct_deploy or full_deploy, the issue is the same
conan install . --output-folder=third-party  --deployer=direct_deploy --deployer-folder=third-party --build=missing

Examine the contents of any *.pc file inside third-party folder and make note of the use of prefix and the values of libdir, includedir, ...

Contents of libuv-static.pc is provided below to illustrate the issue:

prefix=third-party/direct_deploy/libuv
libdir=${prefix}/third-party/direct_deploy/libuv/lib
includedir=${prefix}/third-party/direct_deploy/libuv/include
bindir=${prefix}/third-party/direct_deploy/libuv/bin

Name: libuv-static
Description: Conan package: libuv-static
Version: 1.48.0
Libs: -L"${libdir}" -luv
Cflags: -I"${includedir}"

Notice that the value of the prefix is repeated for libdir, includedir, bindir...

The causes issues for the build system I am using (gn + ninja). I am not sure how it could work for other build systems either.

Anyway, I chased the bug down and isolated it to the function _get_formatted_dirs(...) in `conan/tools/gnu/pkgconfigdeps.py``. For the version I am on, the code looks as below:

    @staticmethod
    def _get_formatted_dirs(folder_name, folders, prefix_path_):
        ret = {}
        for i, directory in enumerate(folders):
            directory = os.path.normpath(directory).replace("\\", "/")
            prefix = ""
            if not os.path.isabs(directory):
                prefix = "${prefix}/"
            elif directory.startswith(prefix_path_):
                prefix = "${prefix}/"
                directory = os.path.relpath(directory, prefix_path_).replace("\\", "/")
            suffix = str(i) if i else ""
            var_name = f"{folder_name}{suffix}"
            ret[var_name] = f"{prefix}{directory}"
        return ret

This code above does the right thing only for the shared dependency *.pc file generation.

  1. The fix I can't claim that I know the implications but I tested the code below and it works now for both use cases correctly. Please review and let me know if you want me to submit a PR. Happy if I don't have to and someone with more knowledge of conan than me can review and fix more quickly.
    @staticmethod
    def _get_formatted_dirs(folder_name, folders, prefix_path_):
        ret = {}
        prefix = "${prefix}/"
        for i, directory in enumerate(folders):
            directory = os.path.normpath(directory).replace("\\", "/")
            directory = os.path.relpath(directory, prefix_path_).replace("\\", "/")
            suffix = str(i) if i else ""
            var_name = f"{folder_name}{suffix}"
            ret[var_name] = f"{prefix}{directory}"
        return ret

With this fix in place, the *.pc files are generated correctly. Here is libuv-static.pc after the fix

prefix=third-party/direct_deploy/libuv
libdir=${prefix}/lib
includedir=${prefix}/include
bindir=${prefix}/bin

Name: libuv-static
Description: Conan package: libuv-static
Version: 1.48.0
Libs: -L"${libdir}" -luv
Cflags: -I"${includedir}"
franramirez688 commented 4 days ago

HI @vijay8i

Thanks a lot for reporting it and the steps to replicate it. I could reproduce it on my own 👍 I'll try to open a PR to fix this today. Indeed, the piece of code that fails is that. Thanks!