From 91d95b0e14cdd54875e0eead8e400920ab0a83c0 Mon Sep 17 00:00:00 2001 From: Enhex Date: Thu, 21 Nov 2024 00:41:17 +0200 Subject: [PATCH 1/2] rename PremakeDeps to PremakeMultiDeps and add single configuration PremakeDeps --- conan/internal/api/install/generators.py | 1 + conan/tools/premake/__init__.py | 3 +- conan/tools/premake/premakedeps.py | 251 +++-------------- conan/tools/premake/premakemultideps.py | 265 ++++++++++++++++++ .../toolchains/premake/test_premakedeps.py | 64 +---- .../premake/test_premakemultideps.py | 64 +++++ 6 files changed, 385 insertions(+), 263 deletions(-) create mode 100644 conan/tools/premake/premakemultideps.py create mode 100644 test/integration/toolchains/premake/test_premakemultideps.py diff --git a/conan/internal/api/install/generators.py b/conan/internal/api/install/generators.py index 22e0c6db2eb..3170a15648a 100644 --- a/conan/internal/api/install/generators.py +++ b/conan/internal/api/install/generators.py @@ -29,6 +29,7 @@ "XcodeDeps": "conan.tools.apple", "XcodeToolchain": "conan.tools.apple", "PremakeDeps": "conan.tools.premake", + "PremakeMultiDeps": "conan.tools.premake", "MakeDeps": "conan.tools.gnu", "SConsDeps": "conan.tools.scons", "QbsDeps": "conan.tools.qbs", diff --git a/conan/tools/premake/__init__.py b/conan/tools/premake/__init__.py index 339d38a6b18..d668706da1f 100644 --- a/conan/tools/premake/__init__.py +++ b/conan/tools/premake/__init__.py @@ -1,2 +1,3 @@ from conan.tools.premake.premake import Premake -from conan.tools.premake.premakedeps import PremakeDeps \ No newline at end of file +from conan.tools.premake.premakedeps import PremakeDeps +from conan.tools.premake.premakemultideps import PremakeMultiDeps \ No newline at end of file diff --git a/conan/tools/premake/premakedeps.py b/conan/tools/premake/premakedeps.py index d3eaa3e49e4..a8f125bf038 100644 --- a/conan/tools/premake/premakedeps.py +++ b/conan/tools/premake/premakedeps.py @@ -1,84 +1,8 @@ -import itertools -import glob -import re - from conan.internal import check_duplicated_generator +from conans.model.build_info import CppInfo from conans.util.files import save -# Filename format strings -PREMAKE_VAR_FILE = "conan_{pkgname}_vars{config}.premake5.lua" -PREMAKE_CONF_FILE = "conan_{pkgname}{config}.premake5.lua" -PREMAKE_PKG_FILE = "conan_{pkgname}.premake5.lua" -PREMAKE_ROOT_FILE = "conandeps.premake5.lua" - -# File template format strings -PREMAKE_TEMPLATE_UTILS = """ -function conan_premake_tmerge(dst, src) - for k, v in pairs(src) do - if type(v) == "table" then - if type(conandeps[k] or 0) == "table" then - conan_premake_tmerge(dst[k] or {}, src[k] or {}) - else - dst[k] = v - end - else - dst[k] = v - end - end - return dst -end -""" -PREMAKE_TEMPLATE_VAR = """ -include "conanutils.premake5.lua" - -t_conandeps = {{}} -t_conandeps["{config}"] = {{}} -t_conandeps["{config}"]["{pkgname}"] = {{}} -t_conandeps["{config}"]["{pkgname}"]["includedirs"] = {{{deps.includedirs}}} -t_conandeps["{config}"]["{pkgname}"]["libdirs"] = {{{deps.libdirs}}} -t_conandeps["{config}"]["{pkgname}"]["bindirs"] = {{{deps.bindirs}}} -t_conandeps["{config}"]["{pkgname}"]["libs"] = {{{deps.libs}}} -t_conandeps["{config}"]["{pkgname}"]["system_libs"] = {{{deps.system_libs}}} -t_conandeps["{config}"]["{pkgname}"]["defines"] = {{{deps.defines}}} -t_conandeps["{config}"]["{pkgname}"]["cxxflags"] = {{{deps.cxxflags}}} -t_conandeps["{config}"]["{pkgname}"]["cflags"] = {{{deps.cflags}}} -t_conandeps["{config}"]["{pkgname}"]["sharedlinkflags"] = {{{deps.sharedlinkflags}}} -t_conandeps["{config}"]["{pkgname}"]["exelinkflags"] = {{{deps.exelinkflags}}} -t_conandeps["{config}"]["{pkgname}"]["frameworks"] = {{{deps.frameworks}}} - -if conandeps == nil then conandeps = {{}} end -conan_premake_tmerge(conandeps, t_conandeps) -""" -PREMAKE_TEMPLATE_ROOT_BUILD = """ - includedirs(conandeps[conf][pkg]["includedirs"]) - bindirs(conandeps[conf][pkg]["bindirs"]) - defines(conandeps[conf][pkg]["defines"]) -""" -PREMAKE_TEMPLATE_ROOT_LINK = """ - libdirs(conandeps[conf][pkg]["libdirs"]) - links(conandeps[conf][pkg]["libs"]) - links(conandeps[conf][pkg]["system_libs"]) - links(conandeps[conf][pkg]["frameworks"]) -""" -PREMAKE_TEMPLATE_ROOT_FUNCTION = """ -function {function_name}(conf, pkg) - if conf == nil then -{filter_call} - elseif pkg == nil then - for k,v in pairs(conandeps[conf]) do - {function_name}(conf, k) - end - else -{lua_content} - end -end -""" -PREMAKE_TEMPLATE_ROOT_GLOBAL = """ -function conan_setup(conf, pkg) - conan_setup_build(conf, pkg) - conan_setup_link(conf, pkg) -end -""" +PREMAKE_FILE = "conandeps.premake5.lua" # Helper class that expands cpp_info meta information in lua readable string sequences @@ -111,81 +35,19 @@ def _format_flags(flags): class PremakeDeps(object): - """ - PremakeDeps class generator - conandeps.premake5.lua: unconditional import of all *direct* dependencies only - """ def __init__(self, conanfile): - """ - :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``. - """ - self._conanfile = conanfile - # Tab configuration - self.tab = " " - - # Return value buffer - self.output_files = {} - # Extract configuration and architecture form conanfile - self.configuration = conanfile.settings.build_type - self.architecture = conanfile.settings.arch - def generate(self): - """ - Generates ``conan__vars_.premake5.lua``, ``conan__.premake5.lua``, - and ``conan_.premake5.lua`` files into the ``conanfile.generators_folder``. - """ - check_duplicated_generator(self, self._conanfile) # Current directory is the generators_folder generator_files = self.content for generator_file, content in generator_files.items(): save(generator_file, content) - def _config_suffix(self): - props = [("Configuration", self.configuration), - ("Platform", self.architecture)] - name = "".join("_%s" % v for _, v in props) - return name.lower() - - def _output_lua_file(self, filename, content): - self.output_files[filename] = "\n".join(["#!lua", *content]) - - def _indent_string(self, string, indent=1): - return "\n".join([ - f"{self.tab * indent}{line}" for line in list(filter(None, string.splitlines())) - ]) - - def _premake_filtered(self, content, configuration, architecture, indent=0): - """ - - Surrounds the lua line(s) contained within ``content`` with a premake "filter" and returns the result. - - A "filter" will affect all premake function calls after it's set. It's used to limit following project - setup function call(s) to a certain scope. Here it is used to limit the calls in content to only apply - if the premake ``configuration`` and ``architecture`` matches the parameters in this function call. - """ - lines = list(itertools.chain.from_iterable([cnt.splitlines() for cnt in content])) - return [ - # Set new filter - f'{self.tab * indent}filter {{ "configurations:{configuration}", "architecture:{architecture}" }}', - # Emit content - *[f"{self.tab * indent}{self.tab}{line.strip()}" for line in list(filter(None, lines))], - # Clear active filter - f"{self.tab * indent}filter {{}}", - ] - @property def content(self): - check_duplicated_generator(self, self._conanfile) - - self.output_files = {} - conf_suffix = str(self._config_suffix()) - conf_name = conf_suffix[1::] - - # Global utility file - self._output_lua_file("conanutils.premake5.lua", [PREMAKE_TEMPLATE_UTILS]) - # Extract all dependencies host_req = self._conanfile.dependencies.host test_req = self._conanfile.dependencies.test @@ -196,70 +58,47 @@ def content(self): + list(test_req.items()) \ + list(build_req.items()) - # Process dependencies and accumulate globally required data - pkg_files = [] - dep_names = [] - config_sets = [] - for require, dep in full_req: - dep_name = require.ref.name - dep_names.append(dep_name) - - # Convert and aggregate dependency's - dep_aggregate = dep.cpp_info.aggregated_components() + all_cpp_info = CppInfo() - # Generate config dependent package variable and setup premake file - var_filename = PREMAKE_VAR_FILE.format(pkgname=dep_name, config=conf_suffix) - self._output_lua_file(var_filename, [ - PREMAKE_TEMPLATE_VAR.format(pkgname=dep_name, - config=conf_name, deps=_PremakeTemplate(dep_aggregate)) - ]) - - # Create list of all available profiles by searching on disk - file_pattern = PREMAKE_VAR_FILE.format(pkgname=dep_name, config="_*") - file_regex = PREMAKE_VAR_FILE.format(pkgname=re.escape(dep_name), config="_(([^_]*)_(.*))") - available_files = glob.glob(file_pattern) - # Add filename of current generations var file if not already present - if var_filename not in available_files: - available_files.append(var_filename) - profiles = [ - (regex_res[0], regex_res.group(1), regex_res.group(2), regex_res.group(3)) for regex_res in [ - re.search(file_regex, file_name) for file_name in available_files - ] - ] - config_sets = [profile[1] for profile in profiles] - - # Emit package premake file - pkg_filename = PREMAKE_PKG_FILE.format(pkgname=dep_name) - pkg_files.append(pkg_filename) - self._output_lua_file(pkg_filename, [ - # Includes - *['include "{}"'.format(profile[0]) for profile in profiles], - ]) - - # Output global premake file - self._output_lua_file(PREMAKE_ROOT_FILE, [ - # Includes - *[f'include "{pkg_file}"' for pkg_file in pkg_files], - # Functions - PREMAKE_TEMPLATE_ROOT_FUNCTION.format( - function_name="conan_setup_build", - lua_content=PREMAKE_TEMPLATE_ROOT_BUILD, - filter_call="\n".join( - ["\n".join(self._premake_filtered( - [f'conan_setup_build("{config}")'], config.split("_", 1)[0], config.split("_", 1)[1], 2) - ) for config in config_sets] - ) - ), - PREMAKE_TEMPLATE_ROOT_FUNCTION.format( - function_name="conan_setup_link", - lua_content=PREMAKE_TEMPLATE_ROOT_LINK, - filter_call="\n".join( - ["\n".join(self._premake_filtered( - [f'conan_setup_link("{config}")'], config.split("_", 1)[0], config.split("_", 1)[1], 2) - ) for config in config_sets] - ) - ), - PREMAKE_TEMPLATE_ROOT_GLOBAL - ]) - - return self.output_files + # merge all dependencies + for require, dep in full_req: + all_cpp_info.merge(dep.cpp_info.aggregated_components()) + + ret = {} # filename -> file content + + template = ('conan_includedirs = {{{deps.includedirs}}}\n' + 'conan_libdirs = {{{deps.libdirs}}}\n' + 'conan_bindirs = {{{deps.bindirs}}}\n' + 'conan_libs = {{{deps.libs}}}\n' + 'conan_system_libs = {{{deps.system_libs}}}\n' + 'conan_defines = {{{deps.defines}}}\n' + 'conan_cxxflags = {{{deps.cxxflags}}}\n' + 'conan_cflags = {{{deps.cflags}}}\n' + 'conan_sharedlinkflags = {{{deps.sharedlinkflags}}}\n' + 'conan_exelinkflags = {{{deps.exelinkflags}}}\n' + 'conan_frameworks = {{{deps.frameworks}}}\n') + + sections = ["#!lua"] + + deps = _PremakeTemplate(all_cpp_info) + all_flags = template.format(deps=deps) + sections.append(all_flags) + sections.append( + "function conan_setup()\n" + " configurations{conan_build_type}\n" + " architecture(conan_arch)\n" + " includedirs{conan_includedirs}\n" + " libdirs{conan_libdirs}\n" + " links{conan_libs}\n" + " links{conan_system_libs}\n" + " links{conan_frameworks}\n" + " defines{conan_defines}\n" + " bindirs{conan_bindirs}\n" + " buildoptions{conan_cflags}\n" + " buildoptions{conan_cxxflags}\n" + " linkoptions{conan_sharedlinkflags}\n" + " linkoptions{conan_exelinkflags}\n" + "end\n") + ret[PREMAKE_FILE] = "\n".join(sections) + + return ret diff --git a/conan/tools/premake/premakemultideps.py b/conan/tools/premake/premakemultideps.py new file mode 100644 index 00000000000..76ed54197eb --- /dev/null +++ b/conan/tools/premake/premakemultideps.py @@ -0,0 +1,265 @@ +import itertools +import glob +import re + +from conan.internal import check_duplicated_generator +from conans.util.files import save + +# Filename format strings +PREMAKE_VAR_FILE = "conan_{pkgname}_vars{config}.premake5.lua" +PREMAKE_CONF_FILE = "conan_{pkgname}{config}.premake5.lua" +PREMAKE_PKG_FILE = "conan_{pkgname}.premake5.lua" +PREMAKE_ROOT_FILE = "conandeps.premake5.lua" + +# File template format strings +PREMAKE_TEMPLATE_UTILS = """ +function conan_premake_tmerge(dst, src) + for k, v in pairs(src) do + if type(v) == "table" then + if type(conandeps[k] or 0) == "table" then + conan_premake_tmerge(dst[k] or {}, src[k] or {}) + else + dst[k] = v + end + else + dst[k] = v + end + end + return dst +end +""" +PREMAKE_TEMPLATE_VAR = """ +include "conanutils.premake5.lua" + +t_conandeps = {{}} +t_conandeps["{config}"] = {{}} +t_conandeps["{config}"]["{pkgname}"] = {{}} +t_conandeps["{config}"]["{pkgname}"]["includedirs"] = {{{deps.includedirs}}} +t_conandeps["{config}"]["{pkgname}"]["libdirs"] = {{{deps.libdirs}}} +t_conandeps["{config}"]["{pkgname}"]["bindirs"] = {{{deps.bindirs}}} +t_conandeps["{config}"]["{pkgname}"]["libs"] = {{{deps.libs}}} +t_conandeps["{config}"]["{pkgname}"]["system_libs"] = {{{deps.system_libs}}} +t_conandeps["{config}"]["{pkgname}"]["defines"] = {{{deps.defines}}} +t_conandeps["{config}"]["{pkgname}"]["cxxflags"] = {{{deps.cxxflags}}} +t_conandeps["{config}"]["{pkgname}"]["cflags"] = {{{deps.cflags}}} +t_conandeps["{config}"]["{pkgname}"]["sharedlinkflags"] = {{{deps.sharedlinkflags}}} +t_conandeps["{config}"]["{pkgname}"]["exelinkflags"] = {{{deps.exelinkflags}}} +t_conandeps["{config}"]["{pkgname}"]["frameworks"] = {{{deps.frameworks}}} + +if conandeps == nil then conandeps = {{}} end +conan_premake_tmerge(conandeps, t_conandeps) +""" +PREMAKE_TEMPLATE_ROOT_BUILD = """ + includedirs(conandeps[conf][pkg]["includedirs"]) + bindirs(conandeps[conf][pkg]["bindirs"]) + defines(conandeps[conf][pkg]["defines"]) +""" +PREMAKE_TEMPLATE_ROOT_LINK = """ + libdirs(conandeps[conf][pkg]["libdirs"]) + links(conandeps[conf][pkg]["libs"]) + links(conandeps[conf][pkg]["system_libs"]) + links(conandeps[conf][pkg]["frameworks"]) +""" +PREMAKE_TEMPLATE_ROOT_FUNCTION = """ +function {function_name}(conf, pkg) + if conf == nil then +{filter_call} + elseif pkg == nil then + for k,v in pairs(conandeps[conf]) do + {function_name}(conf, k) + end + else +{lua_content} + end +end +""" +PREMAKE_TEMPLATE_ROOT_GLOBAL = """ +function conan_setup(conf, pkg) + conan_setup_build(conf, pkg) + conan_setup_link(conf, pkg) +end +""" + + +# Helper class that expands cpp_info meta information in lua readable string sequences +class _PremakeTemplate(object): + def __init__(self, dep_cpp_info): + def _format_paths(paths): + if not paths: + return "" + return ",\n".join(f'"{p}"'.replace("\\", "/") for p in paths) + + def _format_flags(flags): + if not flags: + return "" + return ", ".join('"%s"' % p.replace('"', '\\"') for p in flags) + + self.includedirs = _format_paths(dep_cpp_info.includedirs) + self.libdirs = _format_paths(dep_cpp_info.libdirs) + self.bindirs = _format_paths(dep_cpp_info.bindirs) + self.libs = _format_flags(dep_cpp_info.libs) + self.system_libs = _format_flags(dep_cpp_info.system_libs) + self.defines = _format_flags(dep_cpp_info.defines) + self.cxxflags = _format_flags(dep_cpp_info.cxxflags) + self.cflags = _format_flags(dep_cpp_info.cflags) + self.sharedlinkflags = _format_flags(dep_cpp_info.sharedlinkflags) + self.exelinkflags = _format_flags(dep_cpp_info.exelinkflags) + self.frameworks = ", ".join('"%s.framework"' % p.replace('"', '\\"') for p in + dep_cpp_info.frameworks) if dep_cpp_info.frameworks else "" + self.sysroot = f"{dep_cpp_info.sysroot}".replace("\\", "/") \ + if dep_cpp_info.sysroot else "" + + +class PremakeMultiDeps(object): + """ + PremakeMultiDeps class generator + conandeps.premake5.lua: unconditional import of all *direct* dependencies only + """ + + def __init__(self, conanfile): + """ + :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``. + """ + + self._conanfile = conanfile + + # Tab configuration + self.tab = " " + + # Return value buffer + self.output_files = {} + # Extract configuration and architecture form conanfile + self.configuration = conanfile.settings.build_type + self.architecture = conanfile.settings.arch + + def generate(self): + """ + Generates ``conan__vars_.premake5.lua``, ``conan__.premake5.lua``, + and ``conan_.premake5.lua`` files into the ``conanfile.generators_folder``. + """ + + check_duplicated_generator(self, self._conanfile) + # Current directory is the generators_folder + generator_files = self.content + for generator_file, content in generator_files.items(): + save(generator_file, content) + + def _config_suffix(self): + props = [("Configuration", self.configuration), + ("Platform", self.architecture)] + name = "".join("_%s" % v for _, v in props) + return name.lower() + + def _output_lua_file(self, filename, content): + self.output_files[filename] = "\n".join(["#!lua", *content]) + + def _indent_string(self, string, indent=1): + return "\n".join([ + f"{self.tab * indent}{line}" for line in list(filter(None, string.splitlines())) + ]) + + def _premake_filtered(self, content, configuration, architecture, indent=0): + """ + - Surrounds the lua line(s) contained within ``content`` with a premake "filter" and returns the result. + - A "filter" will affect all premake function calls after it's set. It's used to limit following project + setup function call(s) to a certain scope. Here it is used to limit the calls in content to only apply + if the premake ``configuration`` and ``architecture`` matches the parameters in this function call. + """ + lines = list(itertools.chain.from_iterable([cnt.splitlines() for cnt in content])) + return [ + # Set new filter + f'{self.tab * indent}filter {{ "configurations:{configuration}", "architecture:{architecture}" }}', + # Emit content + *[f"{self.tab * indent}{self.tab}{line.strip()}" for line in list(filter(None, lines))], + # Clear active filter + f"{self.tab * indent}filter {{}}", + ] + + @property + def content(self): + check_duplicated_generator(self, self._conanfile) + + self.output_files = {} + conf_suffix = str(self._config_suffix()) + conf_name = conf_suffix[1::] + + # Global utility file + self._output_lua_file("conanutils.premake5.lua", [PREMAKE_TEMPLATE_UTILS]) + + # Extract all dependencies + host_req = self._conanfile.dependencies.host + test_req = self._conanfile.dependencies.test + build_req = self._conanfile.dependencies.build + + # Merge into one list + full_req = list(host_req.items()) \ + + list(test_req.items()) \ + + list(build_req.items()) + + # Process dependencies and accumulate globally required data + pkg_files = [] + dep_names = [] + config_sets = [] + for require, dep in full_req: + dep_name = require.ref.name + dep_names.append(dep_name) + + # Convert and aggregate dependency's + dep_aggregate = dep.cpp_info.aggregated_components() + + # Generate config dependent package variable and setup premake file + var_filename = PREMAKE_VAR_FILE.format(pkgname=dep_name, config=conf_suffix) + self._output_lua_file(var_filename, [ + PREMAKE_TEMPLATE_VAR.format(pkgname=dep_name, + config=conf_name, deps=_PremakeTemplate(dep_aggregate)) + ]) + + # Create list of all available profiles by searching on disk + file_pattern = PREMAKE_VAR_FILE.format(pkgname=dep_name, config="_*") + file_regex = PREMAKE_VAR_FILE.format(pkgname=re.escape(dep_name), config="_(([^_]*)_(.*))") + available_files = glob.glob(file_pattern) + # Add filename of current generations var file if not already present + if var_filename not in available_files: + available_files.append(var_filename) + profiles = [ + (regex_res[0], regex_res.group(1), regex_res.group(2), regex_res.group(3)) for regex_res in [ + re.search(file_regex, file_name) for file_name in available_files + ] + ] + config_sets = [profile[1] for profile in profiles] + + # Emit package premake file + pkg_filename = PREMAKE_PKG_FILE.format(pkgname=dep_name) + pkg_files.append(pkg_filename) + self._output_lua_file(pkg_filename, [ + # Includes + *['include "{}"'.format(profile[0]) for profile in profiles], + ]) + + # Output global premake file + self._output_lua_file(PREMAKE_ROOT_FILE, [ + # Includes + *[f'include "{pkg_file}"' for pkg_file in pkg_files], + # Functions + PREMAKE_TEMPLATE_ROOT_FUNCTION.format( + function_name="conan_setup_build", + lua_content=PREMAKE_TEMPLATE_ROOT_BUILD, + filter_call="\n".join( + ["\n".join(self._premake_filtered( + [f'conan_setup_build("{config}")'], config.split("_", 1)[0], config.split("_", 1)[1], 2) + ) for config in config_sets] + ) + ), + PREMAKE_TEMPLATE_ROOT_FUNCTION.format( + function_name="conan_setup_link", + lua_content=PREMAKE_TEMPLATE_ROOT_LINK, + filter_call="\n".join( + ["\n".join(self._premake_filtered( + [f'conan_setup_link("{config}")'], config.split("_", 1)[0], config.split("_", 1)[1], 2) + ) for config in config_sets] + ) + ), + PREMAKE_TEMPLATE_ROOT_GLOBAL + ]) + + return self.output_files diff --git a/test/integration/toolchains/premake/test_premakedeps.py b/test/integration/toolchains/premake/test_premakedeps.py index 5beafc197dd..c1e789df7fc 100644 --- a/test/integration/toolchains/premake/test_premakedeps.py +++ b/test/integration/toolchains/premake/test_premakedeps.py @@ -1,64 +1,16 @@ import textwrap -from conan.test.utils.tools import TestClient - - -def assert_vars_file(client, configuration): - contents = client.load(f"conan_pkg.name-more+_vars_{configuration}_x86_64.premake5.lua") - assert f'include "conanutils.premake5.lua"' in contents - assert f't_conandeps = {{}}' in contents - assert f't_conandeps["{configuration}_x86_64"] = {{}}' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"] = {{}}' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["includedirs"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["libdirs"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["bindirs"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["libs"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["system_libs"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["defines"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["cxxflags"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["cflags"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["sharedlinkflags"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["exelinkflags"]' in contents - assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["frameworks"]' in contents - assert f'if conandeps == nil then conandeps = {{}} end' in contents - assert f'conan_premake_tmerge(conandeps, t_conandeps)' in contents +from conans.test.utils.tools import TestClient def test_premakedeps(): - # Create package - client = TestClient() conanfile = textwrap.dedent(""" - from conan import ConanFile - class Pkg(ConanFile): - settings = "os", "compiler", "build_type", "arch" - name = "pkg.name-more+" - version = "1.0" - - def package_info(self): - self.cpp_info.components["libmpdecimal++"].libs = ["libmp++"] - self.cpp_info.components["mycomp.some-comp+"].libs = ["mylib"] - self.cpp_info.components["libmpdecimal++"].requires = ["mycomp.some-comp+"] + [generators] + PremakeDeps """) - client.save({"conanfile.py": conanfile}, clean_first=True) - client.run("create . -s arch=x86_64 -s build_type=Debug") - client.run("create . -s arch=x86_64 -s build_type=Release") - - # Run conan - client.run("install --require=pkg.name-more+/1.0@ -g PremakeDeps -s arch=x86_64 -s build_type=Debug") - client.run("install --require=pkg.name-more+/1.0@ -g PremakeDeps -s arch=x86_64 -s build_type=Release") - - # Assert root lua file - contents = client.load("conandeps.premake5.lua") - assert 'include "conan_pkg.name-more+.premake5.lua"' in contents - assert 'function conan_setup_build(conf, pkg)' in contents - assert 'function conan_setup_link(conf, pkg)' in contents - assert 'function conan_setup(conf, pkg)' in contents - - # Assert package root file - contents = client.load("conan_pkg.name-more+.premake5.lua") - assert 'include "conan_pkg.name-more+_vars_debug_x86_64.premake5.lua"' in contents - assert 'include "conan_pkg.name-more+_vars_release_x86_64.premake5.lua"' in contents + client = TestClient() + client.save({"conanfile.txt": conanfile}, clean_first=True) + client.run("install .") - # Assert package per configuration files - assert_vars_file(client, 'debug') - assert_vars_file(client, 'release') + contents = client.load("conandeps.premake.lua") + assert 'function conan_basic_setup()' in contents diff --git a/test/integration/toolchains/premake/test_premakemultideps.py b/test/integration/toolchains/premake/test_premakemultideps.py new file mode 100644 index 00000000000..5beafc197dd --- /dev/null +++ b/test/integration/toolchains/premake/test_premakemultideps.py @@ -0,0 +1,64 @@ +import textwrap + +from conan.test.utils.tools import TestClient + + +def assert_vars_file(client, configuration): + contents = client.load(f"conan_pkg.name-more+_vars_{configuration}_x86_64.premake5.lua") + assert f'include "conanutils.premake5.lua"' in contents + assert f't_conandeps = {{}}' in contents + assert f't_conandeps["{configuration}_x86_64"] = {{}}' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"] = {{}}' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["includedirs"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["libdirs"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["bindirs"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["libs"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["system_libs"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["defines"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["cxxflags"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["cflags"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["sharedlinkflags"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["exelinkflags"]' in contents + assert f't_conandeps["{configuration}_x86_64"]["pkg.name-more+"]["frameworks"]' in contents + assert f'if conandeps == nil then conandeps = {{}} end' in contents + assert f'conan_premake_tmerge(conandeps, t_conandeps)' in contents + + +def test_premakedeps(): + # Create package + client = TestClient() + conanfile = textwrap.dedent(""" + from conan import ConanFile + class Pkg(ConanFile): + settings = "os", "compiler", "build_type", "arch" + name = "pkg.name-more+" + version = "1.0" + + def package_info(self): + self.cpp_info.components["libmpdecimal++"].libs = ["libmp++"] + self.cpp_info.components["mycomp.some-comp+"].libs = ["mylib"] + self.cpp_info.components["libmpdecimal++"].requires = ["mycomp.some-comp+"] + """) + client.save({"conanfile.py": conanfile}, clean_first=True) + client.run("create . -s arch=x86_64 -s build_type=Debug") + client.run("create . -s arch=x86_64 -s build_type=Release") + + # Run conan + client.run("install --require=pkg.name-more+/1.0@ -g PremakeDeps -s arch=x86_64 -s build_type=Debug") + client.run("install --require=pkg.name-more+/1.0@ -g PremakeDeps -s arch=x86_64 -s build_type=Release") + + # Assert root lua file + contents = client.load("conandeps.premake5.lua") + assert 'include "conan_pkg.name-more+.premake5.lua"' in contents + assert 'function conan_setup_build(conf, pkg)' in contents + assert 'function conan_setup_link(conf, pkg)' in contents + assert 'function conan_setup(conf, pkg)' in contents + + # Assert package root file + contents = client.load("conan_pkg.name-more+.premake5.lua") + assert 'include "conan_pkg.name-more+_vars_debug_x86_64.premake5.lua"' in contents + assert 'include "conan_pkg.name-more+_vars_release_x86_64.premake5.lua"' in contents + + # Assert package per configuration files + assert_vars_file(client, 'debug') + assert_vars_file(client, 'release') From 0d333c30332b9ef3e4fe6e8f30079e288f425cbd Mon Sep 17 00:00:00 2001 From: Enhex Date: Thu, 21 Nov 2024 01:03:07 +0200 Subject: [PATCH 2/2] add missing variables --- conan/tools/premake/premakedeps.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/conan/tools/premake/premakedeps.py b/conan/tools/premake/premakedeps.py index a8f125bf038..ef16f3ea177 100644 --- a/conan/tools/premake/premakedeps.py +++ b/conan/tools/premake/premakedeps.py @@ -80,6 +80,11 @@ def content(self): sections = ["#!lua"] + sections.extend( + ['conan_build_type = "{0}"'.format(str(self._conanfile.settings.build_type)), + 'conan_arch = "{0}"'.format(str(self._conanfile.settings.get_safe("arch"))), + ""]) + deps = _PremakeTemplate(all_cpp_info) all_flags = template.format(deps=deps) sections.append(all_flags)