Skip to content

Commit

Permalink
Added get_gnu_deps_flags. Added functional test
Browse files Browse the repository at this point in the history
  • Loading branch information
franramirez688 committed Jun 30, 2022
1 parent b7a8198 commit 5916833
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 52 deletions.
2 changes: 1 addition & 1 deletion conan/tools/gnu/__init__.py
@@ -1,5 +1,5 @@
from conan.tools.gnu.autotools import Autotools
from conan.tools.gnu.autotoolstoolchain import AutotoolsToolchain
from conan.tools.gnu.autotoolsdeps import AutotoolsDeps
from conan.tools.gnu.autotoolsdeps import AutotoolsDeps, get_gnu_deps_flags
from conan.tools.gnu.pkgconfig import PkgConfig
from conan.tools.gnu.pkgconfigdeps import PkgConfigDeps
115 changes: 64 additions & 51 deletions conan/tools/gnu/autotoolsdeps.py
Expand Up @@ -4,66 +4,79 @@
from conans.model.new_build_info import NewCppInfo


def _get_cpp_info(deps):
ret = NewCppInfo()
for dep in deps:
dep_cppinfo = dep.cpp_info.aggregated_components()
# In case we have components, aggregate them, we do not support isolated
# "targets" with autotools
ret.merge(dep_cppinfo)
return ret


def _rpaths_flags(deps):
flags = []
for dep in deps:
flags.extend(["-Wl,-rpath -Wl,{}".format(libdir) for libdir in dep.cpp_info.libdirs
if dep.options.get_safe("shared", False)])
return flags


def ordered_deps(conanfile):
deps = conanfile.dependencies.host.topological_sort
return[dep for dep in reversed(deps.values())]


def get_gnu_deps_flags(conanfile):
"""
Given a ConanFile object, this function returns all the GNU flags from all the
dependencies.
:param conanfile: The current recipe object. Always use ``self``.
:return: ``tuple`` of all the GNU flags.
"""
deps = ordered_deps(conanfile)
flags = GnuDepsFlags(conanfile, _get_cpp_info(deps))

# cpp_flags
cpp_flags = []
cpp_flags.extend(flags.include_paths)
cpp_flags.extend(flags.defines)

# Ldflags
ldflags = flags.sharedlinkflags
ldflags.extend(flags.exelinkflags)
ldflags.extend(flags.frameworks)
ldflags.extend(flags.framework_paths)
ldflags.extend(flags.lib_paths)

# set the rpath in Macos so that the library are found in the configure step
if conanfile.settings.get_safe("os") == "Macos":
ldflags.extend(_rpaths_flags(deps))

# libs
libs = flags.libs
libs.extend(flags.system_libs)

# cflags
cflags = flags.cflags
cxxflags = flags.cxxflags
return cflags, cxxflags, cpp_flags, libs, ldflags


class AutotoolsDeps:
def __init__(self, conanfile):
self._conanfile = conanfile
self._environment = None
self._ordered_deps = []
check_using_build_profile(self._conanfile)

@property
def ordered_deps(self):
if not self._ordered_deps:
deps = self._conanfile.dependencies.host.topological_sort
self._ordered_deps = [dep for dep in reversed(deps.values())]
return self._ordered_deps

def _get_cpp_info(self):
ret = NewCppInfo()
for dep in self.ordered_deps:
dep_cppinfo = dep.cpp_info.aggregated_components()
# In case we have components, aggregate them, we do not support isolated
# "targets" with autotools
ret.merge(dep_cppinfo)
return ret

def _rpaths_flags(self):
flags = []
for dep in self.ordered_deps:
flags.extend(["-Wl,-rpath -Wl,{}".format(libdir) for libdir in dep.cpp_info.libdirs
if dep.options.get_safe("shared", False)])
return flags

@property
def environment(self):
# TODO: Seems we want to make this uniform, equal to other generators
if self._environment is None:
flags = GnuDepsFlags(self._conanfile, self._get_cpp_info())

# cpp_flags
cpp_flags = []
cpp_flags.extend(flags.include_paths)
cpp_flags.extend(flags.defines)

# Ldflags
ldflags = flags.sharedlinkflags
ldflags.extend(flags.exelinkflags)
ldflags.extend(flags.frameworks)
ldflags.extend(flags.framework_paths)
ldflags.extend(flags.lib_paths)

## set the rpath in Macos so that the library are found in the configure step
if self._conanfile.settings.get_safe("os") == "Macos":
ldflags.extend(self._rpaths_flags())

# libs
libs = flags.libs
libs.extend(flags.system_libs)

# cflags
cflags = flags.cflags
cxxflags = flags.cxxflags

# Get all the GNU flags from all the dependencies
cflags, cxxflags, cpp_flags, libs, ldflags = get_gnu_deps_flags(self._conanfile)
# Create the environment
env = Environment()
env.append("CPPFLAGS", cpp_flags)
env.append("LIBS", libs)
Expand All @@ -76,5 +89,5 @@ def environment(self):
def vars(self, scope="build"):
return self.environment.vars(self._conanfile, scope=scope)

def generate(self, scope="build"):
def generate(self, scope="build"):
self.vars(scope).save_script("conanautotoolsdeps")
@@ -0,0 +1,65 @@
import textwrap
import platform

import pytest

from conans.test.assets.sources import gen_function_cpp
from conans.test.functional.toolchains.meson._base import TestMesonBase
from conans.test.utils.tools import TestClient


class TestMesonToolchainAndGnuFlags(TestMesonBase):

@pytest.mark.skipif(platform.system() == "Windows", reason="Unix only")
def test_mesontoolchain_using_gnu_deps_flags(self):
client = TestClient(path_with_spaces=False)
client.run("new hello/0.1 -s")
client.run("create . hello/0.1@ %s" % self._settings_str)
app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])

conanfile_py = textwrap.dedent("""
from conan import ConanFile
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.gnu import get_gnu_deps_flags
class App(ConanFile):
settings = "os", "arch", "compiler", "build_type"
requires = "hello/0.1"
def layout(self):
self.folders.build = "build"
def generate(self):
# Get GNU flags from all the dependencies
cflags, cxxflags, cpp_flags, libs, ldflags = get_gnu_deps_flags(self)
tc = MesonToolchain(self)
# Extend flags to MesonToolchain
tc.c_args.extend(cpp_flags)
tc.cpp_args.extend(cpp_flags)
tc.c_link_args.extend(ldflags)
tc.cpp_link_args.extend(ldflags)
tc.generate()
def build(self):
meson = Meson(self)
meson.configure()
meson.build()
""")

meson_build = textwrap.dedent("""
project('tutorial', 'cpp')
cxx = meson.get_compiler('cpp')
hello = cxx.find_library('hello', required: true)
executable('demo', 'main.cpp', dependencies: hello)
""")

client.save({"conanfile.py": conanfile_py,
"meson.build": meson_build,
"main.cpp": app},
clean_first=True)

client.run("install . %s" % self._settings_str)
client.run("build .")
assert "[2/2] Linking target demo" in client.out

0 comments on commit 5916833

Please sign in to comment.