Skip to content

Commit 7b422f0

Browse files
committed
WIP: added premake toolchain and updated premake generator
1 parent 3678ee1 commit 7b422f0

File tree

5 files changed

+213
-2
lines changed

5 files changed

+213
-2
lines changed

conan/tools/premake/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from conan.tools.premake.premake import Premake
2-
from conan.tools.premake.premakedeps import PremakeDeps
2+
from conan.tools.premake.premakedeps import PremakeDeps
3+
from conan.tools.premake.toolchain import PremakeToolchain

conan/tools/premake/premake.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ def __init__(self, conanfile):
2020
self.luafile = 'premake5.lua' # Path to the root (premake5) lua file
2121
# (key value pairs. Will translate to "--{key}={value}")
2222
self.arguments = {} # https://premake.github.io/docs/Command-Line-Arguments/
23+
self.arguments["scripts"] = self._conanfile.generators_folder
24+
if self._conanfile.settings.get_safe("arch"):
25+
self.arguments["arch"] = self._conanfile.settings.arch
2326

2427
if "msvc" in self._conanfile.settings.compiler:
2528
msvc_version = PREMAKE_VS_VERSION.get(str(self._conanfile.settings.compiler.version))
2629
self.action = f'vs{msvc_version}'
2730
else:
28-
self.action = 'gmake2'
31+
self.action = 'gmake'
2932

3033
@staticmethod
3134
def _expand_args(args):

conan/tools/premake/toolchain.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import os
2+
import textwrap
3+
4+
from jinja2 import Template
5+
6+
from conan.tools.files import save
7+
8+
9+
class PremakeToolchain:
10+
"""
11+
PremakeToolchain generator
12+
"""
13+
14+
filename = "conantoolchain.premake5.lua"
15+
16+
_premake_file_template = textwrap.dedent(
17+
"""\
18+
#!lua
19+
include("conandeps.premake5.lua")
20+
21+
workspace "{{workspace}}"
22+
location "../../build-{{build_type}}"
23+
{% if cppstd %}
24+
cppdialect "{{cppstd}}"
25+
{% endif %}
26+
{% if cstd %}
27+
cdialect "{{cstd}}"
28+
{% endif %}
29+
location "../../build-{{build_type}}"
30+
targetdir "../../build-{{build_type}}"
31+
conan_setup()
32+
33+
{% if variables %}
34+
defines { {{variables}} }
35+
{% endif %}
36+
"""
37+
)
38+
39+
40+
def __init__(self, conanfile, workspace = '*'):
41+
# '*' is the global workspace
42+
self._conanfile = conanfile
43+
self.workspace = workspace
44+
self.variables = {}
45+
46+
def generate(self):
47+
cppstd = self._conanfile.settings.get_safe("compiler.cppstd")
48+
cstd = self._conanfile.settings.get_safe("compiler.cstd")
49+
if cppstd.startswith("gnu"):
50+
cppstd = f"gnu++{cppstd[3:]}"
51+
52+
build_type = str(self._conanfile.settings.build_type).lower()
53+
54+
formated_variables = ""
55+
for key, value in self.variables.items():
56+
if isinstance(value, bool):
57+
# TODO: var = False not working with C++
58+
value = 1 if value else 0
59+
formated_variables += f'"{key}={value}", '
60+
61+
content = Template(
62+
self._premake_file_template, trim_blocks=True, lstrip_blocks=True
63+
).render(
64+
workspace=self.workspace, build_type=build_type, cppstd=cppstd, cstd=cstd,
65+
variables=formated_variables
66+
)
67+
save(
68+
self,
69+
os.path.join(self._conanfile.generators_folder, self.filename),
70+
content,
71+
)

test/integration/toolchains/premake/test_premake.py

+22
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,25 @@ def build(self):
2222
c.save({"conanfile.py": conanfile})
2323
c.run("build . -s compiler=msvc -s compiler.version=193 -s compiler.runtime=dynamic")
2424
assert "conanfile.py: Running premake5 --file=myproject.lua vs2022 --myarg=myvalue!!" in c.out
25+
26+
27+
28+
def test_premake_compile():
29+
c = TestClient()
30+
conanfile = textwrap.dedent("""
31+
from conan import ConanFile
32+
from conan.tools.premake import Premake
33+
34+
class Pkg(ConanFile):
35+
settings = "os", "compiler", "build_type", "arch"
36+
def run(self, cmd, *args, **kwargs):
37+
self.output.info(f"Running {cmd}!!")
38+
def build(self):
39+
premake = Premake(self)
40+
premake.luafile = "myproject.lua"
41+
premake.arguments = {"myarg": "myvalue"}
42+
premake.configure()
43+
""")
44+
c.save({"conanfile.py": conanfile})
45+
c.run("build . -s compiler=msvc -s compiler.version=193 -s compiler.runtime=dynamic")
46+
assert "conanfile.py: Running premake5 --file=myproject.lua vs2022 --myarg=myvalue!!" in c.out

test/integration/toolchains/premake/test_premakedeps.py

+114
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import textwrap
22

3+
from conan.test.utils.mocks import ConanFileMock
34
from conan.test.utils.tools import TestClient
5+
from conan.tools.env.environment import environment_wrap_command
6+
from conan.test.assets.genconanfile import GenConanfile
47

58

69
def assert_vars_file(client, configuration):
@@ -62,3 +65,114 @@ def package_info(self):
6265
# Assert package per configuration files
6366
assert_vars_file(client, 'debug')
6467
assert_vars_file(client, 'release')
68+
69+
70+
def test_todo():
71+
# Create package
72+
client = TestClient()
73+
# client.run("remote add conancenter https://center2.conan.io")
74+
75+
def run_pkg(msg):
76+
host_arch = client.get_default_host_profile().settings['arch']
77+
cmd_release = environment_wrap_command(ConanFileMock(), f"conanrunenv-release-{host_arch}",
78+
client.current_folder, "dep")
79+
client.run_command(cmd_release)
80+
assert "{}: Hello World Release!".format(msg) in client.out
81+
82+
client.run("new cmake_lib -d name=dep -d version=1.0 -o dep")
83+
84+
consumer_source = textwrap.dedent("""
85+
#include <iostream>
86+
#include "dep.h"
87+
88+
int main(void) {
89+
dep();
90+
std::cout << "Hello World" << std::endl;
91+
return 0;
92+
}
93+
""")
94+
95+
premake5 = textwrap.dedent("""
96+
include("conandeps.premake5.lua")
97+
98+
workspace "HelloWorld"
99+
configurations { "Debug", "Release" }
100+
101+
project "HelloWorld"
102+
kind "ConsoleApp"
103+
language "C++"
104+
targetdir "bin/%{cfg.buildcfg}"
105+
106+
files { "**.h", "**.cpp" }
107+
conan_setup()
108+
109+
filter "configurations:Debug"
110+
defines { "DEBUG" }
111+
symbols "On"
112+
113+
filter "configurations:Release"
114+
defines { "NDEBUG" }
115+
optimize "On"
116+
""")
117+
118+
119+
conanfile = textwrap.dedent("""
120+
from conan import ConanFile
121+
from conan import ConanFile
122+
from conan.tools.files import copy, get, collect_libs, chdir, save, replace_in_file
123+
from conan.tools.layout import basic_layout
124+
from conan.tools.microsoft import MSBuild
125+
from conan.tools.premake import Premake, PremakeDeps
126+
import os
127+
128+
class Pkg(ConanFile):
129+
settings = "os", "compiler", "build_type", "arch"
130+
name = "pkg"
131+
version = "1.0"
132+
exports_sources = '*'
133+
134+
def layout(self):
135+
basic_layout(self, src_folder="src")
136+
137+
def requirements(self):
138+
self.requires("dep/1.0")
139+
140+
def generate(self):
141+
deps = PremakeDeps(self)
142+
deps.generate()
143+
144+
def build(self):
145+
with chdir(self, self.source_folder):
146+
premake = Premake(self)
147+
premake.arguments = {"scripts": "../build-release/conan"}
148+
premake.configure()
149+
if self.settings.os == "Windows":
150+
pass
151+
# msbuild = MSBuild(self)
152+
# msbuild.build("Yojimbo.sln")
153+
else:
154+
build_type = str(self.settings.build_type)
155+
self.run(f"make config={build_type.lower()} -j")
156+
157+
def package(self):
158+
copy(self, "*.h", os.path.join(self.source_folder, "include"), os.path.join(self.package_folder, "include", "pkg"))
159+
for lib in ("*.lib", "*.a"):
160+
copy(self, lib, self.source_folder, os.path.join(self.package_folder, "lib"), keep_path=False)
161+
""")
162+
163+
client.save({"consumer/conanfile.py": conanfile,
164+
"consumer/src/hello.cpp": consumer_source,
165+
"consumer/src/premake5.lua": premake5,
166+
})
167+
168+
client.run("create dep")
169+
client.run("create consumer --build=missing")
170+
build_folder = client.created_layout().build()
171+
print(build_folder)
172+
173+
print(client.out)
174+
client.run("install consumer")
175+
run_pkg("Hello World")
176+
177+
print(client.out)
178+

0 commit comments

Comments
 (0)