Skip to content

Commit

Permalink
PkgConfig uses conanfile.run() instead of independent runner to u…
Browse files Browse the repository at this point in the history
…se Conan environment (#13985)

* serialize cpp_info in package() for PkgConfig full functionality

* Update conan/tools/gnu/pkgconfig.py

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>

---------

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>
  • Loading branch information
memsharded and franramirez688 authored Jul 12, 2023
1 parent b1b1a80 commit 8b6785d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
10 changes: 8 additions & 2 deletions conan/tools/gnu/pkgconfig.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from io import StringIO

from conan.tools.build import cmd_args_to_string
from conan.tools.env import Environment
from conan.errors import ConanException
from conans.util.runners import check_output_runner


class PkgConfig:
Expand All @@ -23,11 +24,16 @@ def __init__(self, conanfile, library, pkg_config_path=None):
def _parse_output(self, option):
executable = self._conanfile.conf.get("tools.gnu:pkg_config", default="pkg-config")
command = cmd_args_to_string([executable, '--' + option, self._library, '--print-errors'])

env = Environment()
if self._pkg_config_path:
env.prepend_path("PKG_CONFIG_PATH", self._pkg_config_path)
with env.vars(self._conanfile).apply():
return check_output_runner(command).strip()
# This way we get the environment from ConanFile, from profile (default buildenv)
output = StringIO()
self._conanfile.run(command, stdout=output)
value = output.getvalue().strip()
return value

def _get_option(self, option):
if option not in self._info:
Expand Down
66 changes: 66 additions & 0 deletions conans/test/functional/toolchains/gnu/test_pkg_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import platform
import textwrap

import pytest

from conans.test.conftest import tools_locations
from conans.test.utils.tools import TestClient


Expand Down Expand Up @@ -68,3 +70,67 @@ def generate(self):
assert "conanfile.py: PROVIDES: libastral = 6.6.6" in c.out
assert "conanfile.py: VERSION: 6.6.6" in c.out
assert "conanfile.py: VARIABLES: /usr/local" in c.out


def test_pkg_config_round_tripe_cpp_info():
""" test that serialize and deserialize CppInfo works
"""
try:
version = tools_locations["pkg_config"]["default"]
exe = tools_locations["pkg_config"]["exe"]
os_ = platform.system()
pkg_config_path = tools_locations["pkg_config"][version]["path"][os_] + "/" + exe
except KeyError:
pytest.skip("pkg-config path not defined")
return

c = TestClient()
conanfile = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.gnu import PkgConfig
from conan.tools import CppInfo
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
exports_sources = "*.pc"
def package(self):
pkg_config = PkgConfig(self, "libastral", pkg_config_path=".")
cpp_info = CppInfo(self)
pkg_config.fill_cpp_info(cpp_info, is_system=False, system_libs=["m"])
cpp_info.save(os.path.join(self.package_folder, "cpp_info.json"))
def package_info(self):
self.cpp_info = CppInfo(self).load("cpp_info.json")
""")
prefix = "C:" if platform.system() == "Windows" else ""
libastral_pc = textwrap.dedent("""\
PC FILE EXAMPLE:
prefix=%s/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libastral
Description: Interface library for Astral data flows
Version: 6.6.6
Libs: -L${libdir}/libastral -lastral -lm -Wl,--whole-archive
Cflags: -I${includedir}/libastral -D_USE_LIBASTRAL
""" % prefix)
c.save({"conanfile.py": conanfile,
"libastral.pc": libastral_pc,
"profile": f"[conf]\ntools.gnu:pkg_config={pkg_config_path}"})
c.run("export .")
c.run("install --requires=pkg/0.1 -pr=profile -g CMakeDeps --build=missing")
pkg_data = c.load("pkg-none-data.cmake")
assert 'set(pkg_DEFINITIONS_NONE "-D_USE_LIBASTRAL")' in pkg_data
assert 'set(pkg_SHARED_LINK_FLAGS_NONE "-Wl,--whole-archive")' in pkg_data
assert 'set(pkg_COMPILE_DEFINITIONS_NONE "_USE_LIBASTRAL")' in pkg_data
assert 'set(pkg_LIBS_NONE astral)' in pkg_data
assert 'set(pkg_SYSTEM_LIBS_NONE m)' in pkg_data
# paths
assert f'set(pkg_INCLUDE_DIRS_NONE "{prefix}/usr/local/include/libastral")' in pkg_data
assert f'set(pkg_LIB_DIRS_NONE "{prefix}/usr/local/lib/libastral")' in pkg_data

0 comments on commit 8b6785d

Please sign in to comment.