Skip to content

Commit fdc9d52

Browse files
authored
Premake generator: better integration (#17898)
Changelog: Feature: Add premake toolchain and improved premake integration in conan with new premake5 Docs: conan-io/docs#4090 Follow premake/premake-core#2441 And test project: https://github.com/perseoGI/conan-premake-example
2 parents 4c91314 + 3366f49 commit fdc9d52

File tree

15 files changed

+966
-30
lines changed

15 files changed

+966
-30
lines changed

conan/api/subapi/new.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ def get_builtin_template(template_name):
9696
from conan.internal.api.new.bazel_7_exe import bazel_exe_files_7
9797
from conan.internal.api.new.autotools_lib import autotools_lib_files
9898
from conan.internal.api.new.autoools_exe import autotools_exe_files
99+
from conan.internal.api.new.premake_lib import premake_lib_files
100+
from conan.internal.api.new.premake_exe import premake_exe_files
99101
from conan.internal.api.new.local_recipes_index import local_recipes_index_files
100102
from conan.internal.api.new.qbs_lib import qbs_lib_files
101103
from conan.internal.api.new.workspace import workspace_files
@@ -114,6 +116,8 @@ def get_builtin_template(template_name):
114116
"bazel_7_exe": bazel_exe_files_7,
115117
"autotools_lib": autotools_lib_files,
116118
"autotools_exe": autotools_exe_files,
119+
"premake_lib": premake_lib_files,
120+
"premake_exe": premake_exe_files,
117121
"alias": alias_file,
118122
"local_recipes_index": local_recipes_index_files,
119123
"qbs_lib": qbs_lib_files,

conan/internal/api/install/generators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"XcodeDeps": "conan.tools.apple",
3131
"XcodeToolchain": "conan.tools.apple",
3232
"PremakeDeps": "conan.tools.premake",
33+
"PremakeToolchain": "conan.tools.premake",
3334
"MakeDeps": "conan.tools.gnu",
3435
"SConsDeps": "conan.tools.scons",
3536
"QbsDeps": "conan.tools.qbs",

conan/internal/api/new/premake_exe.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from conan.internal.api.new.cmake_lib import source_cpp, source_h, test_main
2+
3+
conanfile_exe = """import os
4+
from conan import ConanFile
5+
from conan.tools.files import copy
6+
from conan.tools.layout import basic_layout
7+
from conan.tools.premake import PremakeDeps, PremakeToolchain, Premake
8+
9+
10+
class {{package_name}}Recipe(ConanFile):
11+
name = "{{name}}"
12+
version = "{{version}}"
13+
package_type = "application"
14+
15+
# Optional metadata
16+
license = "<Put the package license here>"
17+
author = "<Put your name here> <And your email here>"
18+
url = "<Package recipe repository url here, for issues about the package>"
19+
description = "<Description of {{ name }} package here>"
20+
topics = ("<Put some tag here>", "<here>", "<and here>")
21+
22+
# Binary configuration
23+
settings = "os", "compiler", "build_type", "arch"
24+
25+
# Sources are located in the same place as this recipe, copy them to the recipe
26+
exports_sources = "premake5.lua", "src/*"
27+
28+
def layout(self):
29+
basic_layout(self)
30+
31+
def generate(self):
32+
deps = PremakeDeps(self)
33+
deps.generate()
34+
tc = PremakeToolchain(self)
35+
tc.generate()
36+
37+
def build(self):
38+
premake = Premake(self)
39+
premake.configure()
40+
premake.build(workspace="{{name.capitalize()}}")
41+
42+
def package(self):
43+
dest_bin = os.path.join(self.package_folder, "bin")
44+
build = os.path.join(self.build_folder, "bin")
45+
copy(self, "{{name}}", build, dest_bin, keep_path=False)
46+
copy(self, "{{name}}.exe", build, dest_bin, keep_path=False)
47+
48+
49+
{% if requires is defined -%}
50+
def requirements(self):
51+
{% for require in requires -%}
52+
self.requires("{{ require }}")
53+
{% endfor %}
54+
{%- endif %}
55+
56+
{% if tool_requires is defined -%}
57+
def build_requirements(self):
58+
{% for require in tool_requires -%}
59+
self.tool_requires("{{ require }}")
60+
{% endfor %}
61+
{%- endif %}
62+
"""
63+
64+
premake5 = """workspace "{{name.capitalize()}}"
65+
configurations { "Debug", "Release" }
66+
67+
project "{{name}}"
68+
kind "ConsoleApp"
69+
language "C++"
70+
files { "src/main.cpp", "src/{{name}}.cpp", "src/{{name}}.h" }
71+
72+
filter "configurations:Debug"
73+
defines { "DEBUG" }
74+
symbols "On"
75+
76+
filter "configurations:Release"
77+
defines { "NDEBUG" }
78+
optimize "On"
79+
"""
80+
81+
test_conanfile_exe_v2 = """
82+
from conan import ConanFile
83+
from conan.tools.build import can_run
84+
85+
86+
class {{package_name}}TestConan(ConanFile):
87+
settings = "os", "compiler", "build_type", "arch"
88+
89+
def requirements(self):
90+
self.requires(self.tested_reference_str)
91+
92+
def test(self):
93+
if can_run(self):
94+
self.run("{{name}}", env="conanrun")
95+
"""
96+
97+
premake_exe_files = {
98+
"conanfile.py": conanfile_exe,
99+
"src/{{name}}.cpp": source_cpp,
100+
"src/{{name}}.h": source_h,
101+
"src/main.cpp": test_main,
102+
"premake5.lua": premake5,
103+
"test_package/conanfile.py": test_conanfile_exe_v2,
104+
}

conan/internal/api/new/premake_lib.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
from conan.internal.api.new.cmake_lib import source_cpp, source_h, test_main
2+
3+
conanfile_sources = """import os
4+
from conan import ConanFile
5+
from conan.tools.files import copy
6+
from conan.tools.layout import basic_layout
7+
from conan.tools.premake import PremakeDeps, PremakeToolchain, Premake
8+
9+
10+
class {{package_name}}Recipe(ConanFile):
11+
name = "{{name}}"
12+
version = "{{version}}"
13+
package_type = "library"
14+
15+
# Optional metadata
16+
license = "<Put the package license here>"
17+
author = "<Put your name here> <And your email here>"
18+
url = "<Package recipe repository url here, for issues about the package>"
19+
description = "<Description of {{ name }} package here>"
20+
topics = ("<Put some tag here>", "<here>", "<and here>")
21+
22+
# Binary configuration
23+
settings = "os", "compiler", "build_type", "arch"
24+
options = {"shared": [True, False], "fPIC": [True, False]}
25+
default_options = {"shared": False, "fPIC": True}
26+
implements = ["auto_shared_fpic"]
27+
28+
# Sources are located in the same place as this recipe, copy them to the recipe
29+
exports_sources = "premake5.lua", "src/*", "include/*"
30+
31+
def layout(self):
32+
basic_layout(self)
33+
{% if requires is defined %}
34+
def requirements(self):
35+
{% for require in requires -%}
36+
self.requires("{{ require }}")
37+
{% endfor %}
38+
{%- endif %}
39+
{%- if tool_requires is defined %}
40+
def build_requirements(self):
41+
{% for require in tool_requires -%}
42+
self.tool_requires("{{ require }}")
43+
{% endfor %}
44+
{%- endif %}
45+
def generate(self):
46+
deps = PremakeDeps(self)
47+
deps.generate()
48+
tc = PremakeToolchain(self)
49+
tc.generate()
50+
51+
def build(self):
52+
premake = Premake(self)
53+
premake.configure()
54+
premake.build(workspace="{{name.capitalize()}}")
55+
56+
def package(self):
57+
copy(self, "*.h", os.path.join(self.source_folder, "include"), os.path.join(self.package_folder, "include"))
58+
59+
for pattern in ("*.lib", "*.a", "*.so*", "*.dylib"):
60+
copy(self, pattern, os.path.join(self.build_folder, "bin"), os.path.join(self.package_folder, "lib"))
61+
copy(self, "*.dll", os.path.join(self.build_folder, "bin"), os.path.join(self.package_folder, "bin"))
62+
63+
def package_info(self):
64+
self.cpp_info.libs = ["{{name}}"]
65+
"""
66+
67+
premake5 = """workspace "{{name.capitalize()}}"
68+
configurations { "Debug", "Release" }
69+
fatalwarnings {"All"}
70+
floatingpoint "Fast"
71+
includedirs { ".", "src", "include" }
72+
73+
project "{{name}}"
74+
cppdialect "C++17"
75+
76+
-- To let conan take control over `kind` of the libraries, DO NOT SET `kind` (StaticLib or
77+
-- SharedLib) in `project` block.
78+
-- kind "<controlled by conan>"
79+
80+
language "C++"
81+
files { "include/*.hpp", "include/*.h", "src/*.cpp" }
82+
83+
filter "configurations:Debug"
84+
defines { "DEBUG" }
85+
symbols "On"
86+
87+
filter "configurations:Release"
88+
defines { "NDEBUG" }
89+
optimize "On"
90+
91+
"""
92+
93+
test_conanfile = """import os
94+
95+
from conan import ConanFile
96+
from conan.tools.layout import basic_layout
97+
from conan.tools.premake import Premake
98+
from conan.tools.build import can_run
99+
100+
101+
class {{package_name}}TestConan(ConanFile):
102+
settings = "os", "compiler", "build_type", "arch"
103+
generators = "PremakeDeps", "PremakeToolchain"
104+
105+
def layout(self):
106+
basic_layout(self)
107+
108+
def requirements(self):
109+
self.requires(self.tested_reference_str)
110+
111+
def build(self):
112+
premake = Premake(self)
113+
premake.configure()
114+
premake.build(workspace="Example")
115+
116+
def test(self):
117+
if can_run(self):
118+
cmd = os.path.join(self.cpp.build.bindir, "bin", "example")
119+
self.run(cmd, env="conanrun")
120+
"""
121+
122+
test_premake5 = """workspace "Example"
123+
configurations { "Debug", "Release" }
124+
125+
project "example"
126+
kind "ConsoleApp"
127+
language "C++"
128+
files { "src/example.cpp" }
129+
130+
filter "configurations:Debug"
131+
defines { "DEBUG" }
132+
symbols "On"
133+
134+
filter "configurations:Release"
135+
defines { "NDEBUG" }
136+
optimize "On"
137+
"""
138+
139+
140+
premake_lib_files = {
141+
"conanfile.py": conanfile_sources,
142+
"src/{{name}}.cpp": source_cpp,
143+
"include/{{name}}.h": source_h,
144+
"premake5.lua": premake5,
145+
"test_package/conanfile.py": test_conanfile,
146+
"test_package/src/example.cpp": test_main,
147+
"test_package/premake5.lua": test_premake5,
148+
}

conan/tools/premake/__init__.py

Lines changed: 2 additions & 1 deletion
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/constants.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Source: https://premake.github.io/docs/architecture/
2+
CONAN_TO_PREMAKE_ARCH = {
3+
"x86": "x86",
4+
"x86_64": "x86_64",
5+
6+
"armv4": "arm",
7+
"armv4i": "arm",
8+
"armv5el": "arm",
9+
"armv5hf": "arm",
10+
"armv6": "arm",
11+
"armv7": "arm",
12+
"armv7hf": "arm",
13+
"armv7s": "arm",
14+
"armv7k": "arm",
15+
16+
"armv8": "arm64",
17+
"armv8_32": "arm64",
18+
"armv8.3": "arm64",
19+
"arm64ec": "arm64",
20+
21+
"e2k-v2": "e2k",
22+
"e2k-v3": "e2k",
23+
"e2k-v4": "e2k",
24+
"e2k-v5": "e2k",
25+
"e2k-v6": "e2k",
26+
"e2k-v7": "e2k",
27+
28+
"riscv64": "riscv64",
29+
30+
"wasm": "wasm32",
31+
"wasm64": "wasm64",
32+
"asm.js": "wasm32",
33+
}

0 commit comments

Comments
 (0)