Add better documentation for s3tc

hotfix/mipmap-alpha-fix
Andrew Cassidy 3 years ago
parent 63978703cd
commit 882c970e27

@ -54,6 +54,7 @@ html_static_path = ['_static']
# -- Options for Autodoc -----------------------------------------------------
add_module_names = False
autodoc_docstring_signature = True
autodoc_default_options = {
'member-order': 'groupwise',

@ -1,12 +1,103 @@
s3tc module
===========
this is some text
The s3tc module provides encoders and decoders for the common S3 Texture Compression formats. BC1-5 encoding is done
internally using a modified version of rgbcx.h.
bc1 module
----------
.. automodule:: quicktex.s3tc.bc1
:members:
:undoc-members:
:special-members:
.. autoclass:: BC1Encoder(BlockEncoder)
.. automethod:: __init__
.. automethod:: set_level
.. autoproperty:: color_mode(self) -> ColorMode
.. autoproperty:: interpolator(self) -> quicktex.s3tc.interpolator.Interpolator
.. autoclass:: quicktex.s3tc.bc1::BC1Encoder.ColorMode
**Advanced API**
Additional properties are provided for finer-grained control over quality and performance
.. autoproperty:: error_mode(self) -> ErrorMode
.. autoproperty:: endpoint_mode(self) -> EndpointMode
.. autoproperty:: two_ls_passes(self) -> bool
.. autoproperty:: two_ep_passes(self) -> bool
.. autoproperty:: two_cf_passes(self) -> bool
.. autoproperty:: exhaustive(self) -> bool
.. autoproperty:: search_rounds(self) -> int
.. autoproperty:: orderings(self) -> tuple[int, int]
.. autoproperty:: power_iterations(self) -> int
.. autoattribute:: max_power_iterations
.. autoattribute:: min_power_iterations
.. autoclass:: quicktex.s3tc.bc1::BC1Encoder.EndpointMode
.. autoclass:: quicktex.s3tc.bc1::BC1Encoder.ErrorMode
.. autoclass:: BC1Decoder(BlockDecoder)
.. automethod:: __init__
.. autoproperty:: interpolator(self) -> quicktex.s3tc.interpolator.Interpolator
.. autoproperty:: write_alpha(self) -> bool
bc3 module
----------
.. automodule:: quicktex.s3tc.bc3
.. autoclass:: BC3Encoder(BlockEncoder)
.. automethod:: __init__
.. autoproperty:: bc1_encoder(self) -> quicktex.s3tc.bc1.BC1Encoder
.. autoproperty:: bc4_encoder(self) -> quicktex.s3tc.bc4.BC4Encoder
.. autoclass:: BC3Decoder(BlockDecoder)
.. automethod:: __init__
.. autoproperty:: bc1_decoder(self) -> quicktex.s3tc.bc1.BC1Decoder
.. autoproperty:: bc4_decoder(self) -> quicktex.s3tc.bc4.BC4Decoder
bc4 module
----------
.. automodule:: quicktex.s3tc.bc4
.. autoclass:: BC4Encoder(BlockEncoder)
.. automethod:: __init__
.. autoproperty:: channel(self) -> int
.. autoclass:: BC4Decoder(BlockDecoder)
.. automethod:: __init__
.. autoproperty:: channel(self) -> int
bc5 module
----------
.. automodule:: quicktex.s3tc.bc5
.. autoclass:: BC5Encoder(BlockEncoder)
.. automethod:: __init__
.. autoproperty:: bc4_encoders(self) -> tuple[quicktex.s3tc.bc4.BC4Encoder]
.. autoproperty:: channels(self) -> tuple[int, int]
.. autoclass:: BC5Decoder(BlockDecoder)
.. automethod:: __init__
.. autoproperty:: bc4_decoders(self) -> tuple[quicktex.s3tc.bc4.BC4Decoder]
.. autoproperty:: channels(self) -> tuple[int, int]
interpolator module
-------------------
.. automodule:: quicktex.s3tc.interpolator
:members:
.. autoclass:: Interpolator
.. autoclass:: InterpolatorRound(Interpolator)
.. autoclass:: InterpolatorNvidia(Interpolator)
.. autoclass:: InterpolatorAMD(Interpolator)

@ -18,8 +18,9 @@
*/
#include <pybind11/pybind11.h>
#include "BlockEncoder.h"
#include "BlockDecoder.h"
#include "BlockEncoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
@ -72,7 +73,6 @@ PYBIND11_MODULE(_quicktex, m) {
m.doc() = "More Stuff";
py::options options;
// options.disable_function_signatures();
// BlockDecoder
py::class_<BlockDecoder> block_decoder(m, "BlockDecoder");

@ -38,8 +38,8 @@ void InitS3TC(py::module_ &m) {
InitInterpolator(s3tc);
InitBC1(s3tc);
// InitBC3(s3tc);
// InitBC4(s3tc);
// InitBC5(s3tc);
InitBC3(s3tc);
InitBC4(s3tc);
InitBC5(s3tc);
}
} // namespace quicktex::bindings

@ -1 +1,3 @@
"""Classes for encoding/decoding BC1 textures"""
from _quicktex._s3tc._bc1 import *

@ -40,42 +40,61 @@ using namespace pybind11::literals;
using InterpolatorPtr = std::shared_ptr<Interpolator>;
void InitBC1(py::module_ &s3tc) {
auto bc1 = s3tc.def_submodule("_bc1", "BC1 encoding/decoding module");
auto bc1 = s3tc.def_submodule("_bc1", "internal bc1 module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
py::options options;
options.disable_function_signatures();
// BC1Encoder
py::class_<BC1Encoder> bc1_encoder(bc1, "BC1Encoder", block_encoder, "Encodes RGB textures to BC1");
py::enum_<BC1Encoder::EndpointMode>(bc1_encoder, "EndpointMode")
.value("LeastSquares", BC1Encoder::EndpointMode::LeastSquares)
.value("BoundingBox", BC1Encoder::EndpointMode::BoundingBox)
.value("BoundingBoxInt", BC1Encoder::EndpointMode::BoundingBoxInt)
.value("PCA", BC1Encoder::EndpointMode::PCA);
py::enum_<BC1Encoder::EndpointMode>(bc1_encoder, "EndpointMode", "Enum representing various methods of finding endpoints in a block.")
.value("LeastSquares", BC1Encoder::EndpointMode::LeastSquares, "Find endpoints using a 2D least squares approach.")
.value("BoundingBox", BC1Encoder::EndpointMode::BoundingBox, "Find endpoints using a simple bounding box. Fast but inaccurate.")
.value("BoundingBoxInt", BC1Encoder::EndpointMode::BoundingBoxInt, "Same as BoundingBox but using integers, slightly faster.")
.value("PCA", BC1Encoder::EndpointMode::PCA, "Find endpoints using Principle Component Analysis. Slowest but highest quality method.");
py::enum_<BC1Encoder::ErrorMode>(bc1_encoder, "ErrorMode")
.value("None", BC1Encoder::ErrorMode::None)
.value("Faster", BC1Encoder::ErrorMode::Faster)
.value("Check2", BC1Encoder::ErrorMode::Check2)
.value("Full", BC1Encoder::ErrorMode::Full);
py::enum_<BC1Encoder::ErrorMode>(bc1_encoder, "ErrorMode", "Enum representing various methods of finding selectors in a block.")
.value("None", BC1Encoder::ErrorMode::None, "The same as Faster but error is not calculated. This disables any cluster-fit options")
.value("Faster", BC1Encoder::ErrorMode::Faster, "Use a slightly lower quality, but ~30% faster MSE evaluation function for 4-color blocks.")
.value("Check2", BC1Encoder::ErrorMode::Check2, "Default error-checking method.")
.value("Full", BC1Encoder::ErrorMode::Full, "Examine all colors to compute selectors/MSE. Slower but slightly higher quality.");
py::enum_<BC1Encoder::ColorMode>(bc1_encoder, "ColorMode")
py::enum_<BC1Encoder::ColorMode>(bc1_encoder, "ColorMode", "Enum representing various methods of writing BC1 blocks.")
.value("FourColor", BC1Encoder::ColorMode::FourColor, "Default color mode. Only 4-color blocks will be output, where color0 > color1")
.value("ThreeColor", BC1Encoder::ColorMode::ThreeColor)
.value("ThreeColorBlack", BC1Encoder::ColorMode::ThreeColorBlack);
.value("ThreeColor", BC1Encoder::ColorMode::ThreeColor, "Additionally use 3-color blocks when they have a lower error, where color0 <= color1")
.value("ThreeColorBlack", BC1Encoder::ColorMode::ThreeColorBlack,
"Additionally use 3-color blocks with black pixels (selector 3). Note that this requires your shader/engine to not sample the alpha channel "
"when using a BC1 texture.");
bc1_encoder.def(py::init<unsigned, BC1Encoder::ColorMode>(), "level"_a = 5, "color_mode"_a = BC1Encoder::ColorMode::FourColor);
bc1_encoder.def(py::init<unsigned, BC1Encoder::ColorMode, InterpolatorPtr>(), "level"_a, "color_mode"_a, "interpolator"_a);
bc1_encoder.def(py::init<unsigned, BC1Encoder::ColorMode, InterpolatorPtr>(), "level"_a, "color_mode"_a, "interpolator"_a, R"pbdoc(
__init__(self, level: int = 5, color_mode=ColorMode.FourColor, interpolator=Interpolator()) -> None
bc1_encoder.def("set_level", &BC1Encoder::SetLevel, "Use a preset quality level, between 0 and 18. For better control, see the advanced API below");
Create a new BC1 encoder with the specified preset level, color mode, and interpolator.
// Advanced API
:param int level: The preset level of the resulting encoder, between 0 and 18 inclusive. See :py:meth:`set_level` for more information. Default: 5.
:param ColorMode color_mode: The color mode of the resulting BC1Encoder. Default: :py:class:`~quicktex.s3tc.bc1.BC1Encoder.ColorMode.FourColor`.
:param Interpolator interpolator: The interpolation mode to use for encoding. Default: :py:class:`~quicktex.s3tc.interpolator.Interpolator`.
)pbdoc");
bc1_encoder.def("set_level", &BC1Encoder::SetLevel, "level"_a, R"pbdoc(
set_level(self, level : int = 5) -> None
bc1_encoder.def_readonly_static("max_power_iterations", &BC1Encoder::max_power_iterations, "Maximum value of :py:attr:`BC1Encoder.power_iterations`.");
bc1_encoder.def_readonly_static("min_power_iterations", &BC1Encoder::min_power_iterations, "Minimum value of :py:attr:`BC1Encoder.power_iterations`.");
Select a preset quality level, between 0 and 18 inclusive. Higher quality levels are slower, but produce blocks that are a closer match to input.
This has no effect on the size of the resulting texture, since BC1 is a fixed-ratio compression method. For better control, see the advanced API below
bc1_encoder.def_property_readonly("interpolator", &BC1Encoder::GetInterpolator, "The interpolator used by this encoder. This is a readonly property.");
bc1_encoder.def_property_readonly("color_mode", &BC1Encoder::GetColorMode, "The color mode used by this encoder. This is a readonly property.");
:param int level: The preset level of the resulting encoder, between 0 and 18 inclusive. Default: 5.
)pbdoc");
bc1_encoder.def_property_readonly("interpolator", &BC1Encoder::GetInterpolator,
"The :py:class:`~quicktex.s3tc.interpolator.Interpolator` used by this encoder. This is a readonly property.");
bc1_encoder.def_property_readonly("color_mode", &BC1Encoder::GetColorMode,
"The :py:class:`~quicktex.s3tc.bc1.BC1Encoder.ColorMode` used by this encoder. This is a readonly property.");
// Advanced API
bc1_encoder.def_property("error_mode", &BC1Encoder::GetErrorMode, &BC1Encoder::SetErrorMode, "The error mode used by this encoder for finding selectors.");
bc1_encoder.def_property("endpoint_mode", &BC1Encoder::GetEndpointMode, &BC1Encoder::SetEndpointMode, "The endpoint mode used by this encoder.");
@ -102,6 +121,9 @@ void InitBC1(py::module_ &s3tc) {
"setting the orderings > 0 enables ordered cluster fit using a lookup table of similar blocks. Value is a tuple of (4 color "
"orders, 3 color orders), where higher values have a higher quality at the expense of performance.");
bc1_encoder.def_readonly_static("max_power_iterations", &BC1Encoder::max_power_iterations);
bc1_encoder.def_readonly_static("min_power_iterations", &BC1Encoder::min_power_iterations);
bc1_encoder.def_property("power_iterations", &BC1Encoder::GetPowerIterations, &BC1Encoder::SetPowerIterations,
"Number of power iterations used with the PCA endpoint mode. Value should be around 4 to 6. "
"Automatically clamped to between :py:const:`BC1Encoder.min_power_iterations` and :py:const:`BC1Encoder.max_power_iterations`");
@ -110,9 +132,16 @@ void InitBC1(py::module_ &s3tc) {
py::class_<BC1Decoder> bc1_decoder(bc1, "BC1Decoder", block_decoder, "Decodes BC1 textures to RGB");
bc1_decoder.def(py::init<bool>(), "write_alpha"_a = false);
bc1_decoder.def(py::init<bool, InterpolatorPtr>(), "write_alpha"_a, "interpolator"_a);
bc1_decoder.def(py::init<bool, InterpolatorPtr>(), "write_alpha"_a, "interpolator"_a, R"pbdoc(
__init__(self, interpolator = Interpolator()) -> None
Create a new BC1 decoder with the specificied interpolator.
:param bool write_alpha: Determines if the alpha channel of the output is written to. Default: False;
:param Interpolator interpolator: The interpolation mode to use for decoding. Default: :py:class:`~quicktex.s3tc.interpolator.Interpolator`.
)pbdoc");
bc1_decoder.def_property_readonly("interpolator", &BC1Decoder::GetInterpolator);
bc1_decoder.def_readwrite("write_alpha", &BC1Decoder::write_alpha);
bc1_decoder.def_property_readonly("interpolator", &BC1Decoder::GetInterpolator, "The interpolator used by this decoder. This is a readonly property.");
bc1_decoder.def_readwrite("write_alpha", &BC1Decoder::write_alpha, "Determines if the alpha channel of the output is written to.");
}
} // namespace quicktex::bindings

@ -41,26 +41,46 @@ using BC1EncoderPtr = std::shared_ptr<BC1Encoder>;
using BC1DecoderPtr = std::shared_ptr<BC1Decoder>;
void InitBC3(py::module_ &s3tc) {
auto bc3 = s3tc.def_submodule("_bc3", "BC3 encoding/decoding module");
auto bc3 = s3tc.def_submodule("_bc3", "internal bc3 module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
py::options options;
options.disable_function_signatures();
// BC3Encoder
py::class_<BC3Encoder> bc3_encoder(bc3, "BC3Encoder", block_encoder);
py::class_<BC3Encoder> bc3_encoder(bc3, "BC3Encoder", block_encoder, "Encodes RGBA textures to BC3");
bc3_encoder.def(py::init<unsigned>(), "level"_a = 5);
bc3_encoder.def(py::init<unsigned, InterpolatorPtr>(), "level"_a, "interpolator"_a);
bc3_encoder.def(py::init<unsigned, InterpolatorPtr>(), "level"_a, "interpolator"_a, R"doc(
__init__(self, level: int = 5, interpolator=Interpolator()) -> None
bc3_encoder.def_property_readonly("bc1_encoder", &BC3Encoder::GetBC1Encoder);
bc3_encoder.def_property_readonly("bc4_encoder", &BC3Encoder::GetBC4Encoder);
Create a new BC3 encoder with the specified preset level and interpolator.
:param int level: The preset level of the resulting encoder, between 0 and 18 inclusive.
See :py:meth:`~quicktex.s3tc.bc1.BC1Encoder.set_level` for more information. Default: 5.
:param Interpolator interpolator: The interpolation mode to use for encoding. Default: :py:class:`~quicktex.s3tc.interpolator.Interpolator`.
)doc");
bc3_encoder.def_property_readonly("bc1_encoder", &BC3Encoder::GetBC1Encoder,
"Internal :py:class:`~quicktex.s3tc.bc1.BC1Encoder` used for RGB data. Readonly.");
bc3_encoder.def_property_readonly("bc4_encoder", &BC3Encoder::GetBC4Encoder,
"Internal :py:class:`~quicktex.s3tc.bc4.BC4Encoder` used for alpha data. Readonly.");
// BC3Decoder
py::class_<BC3Decoder> bc3_decoder(bc3, "BC3Decoder", block_decoder);
py::class_<BC3Decoder> bc3_decoder(bc3, "BC3Decoder", block_decoder, "Decodes BC3 textures to RGBA");
bc3_decoder.def(py::init<>());
bc3_decoder.def(py::init<InterpolatorPtr>(), "interpolator"_a);
bc3_decoder.def(py::init<InterpolatorPtr>(), "interpolator"_a, R"doc(
__init__(interpolator = Interpolator()) -> None
Create a new BC3 decoder with the specified interpolator.
:param Interpolator interpolator: The interpolation mode to use for decoding. Default: :py:class:`~quicktex.s3tc.interpolator.Interpolator`.
)doc");
bc3_decoder.def_property_readonly("bc1_decoder", &BC3Decoder::GetBC1Decoder);
bc3_decoder.def_property_readonly("bc4_decoder", &BC3Decoder::GetBC4Decoder);
bc3_decoder.def_property_readonly("bc1_decoder", &BC3Decoder::GetBC1Decoder,
"Internal :py:class:`~quicktex.s3tc.bc1.BC1Decoder` used for RGB data. Readonly.");
bc3_decoder.def_property_readonly("bc4_decoder", &BC3Decoder::GetBC4Decoder,
"Internal :py:class:`~quicktex.s3tc.bc4.BC4Decoder` used for alpha data. Readonly.");
};
} // namespace quicktex::bindings

@ -34,24 +34,38 @@ namespace py = pybind11;
namespace quicktex::bindings {
using namespace quicktex::s3tc;
using namespace quicktex::s3tc ;
using namespace quicktex::s3tc;
void InitBC4(py::module_ &s3tc) {
auto bc4 = s3tc.def_submodule("_bc4", "BC4 encoding/decoding module");
auto bc4 = s3tc.def_submodule("_bc4", "internal bc4 module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
py::options options;
options.disable_function_signatures();
// BC4Encoder
py::class_<BC4Encoder> bc4_encoder(bc4, "BC4Encoder", block_encoder);
py::class_<BC4Encoder> bc4_encoder(bc4, "BC4Encoder", block_encoder, "Encodes single-channel textures to BC4.");
bc4_encoder.def(py::init<uint8_t>(), py::arg("channel") = 3, R"doc(
__init__(channel : int = 3) -> None
Create a new BC4 encoder with the specified channel
bc4_encoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_encoder.def_property_readonly("channel", &BC4Encoder::GetChannel, "The channel to read from. 0 to 3 inclusive. Readonly.");
:param int channel: the channel that will be read from. 0 to 3 inclusive. Default: 3 (alpha).
)doc");
bc4_encoder.def_property_readonly("channel", &BC4Encoder::GetChannel, "The channel that will be read from. 0 to 3 inclusive. Readonly.");
// BC4Decoder
py::class_<BC4Decoder> bc4_decoder(bc4, "BC4Decoder", block_decoder);
py::class_<BC4Decoder> bc4_decoder(bc4, "BC4Decoder", block_decoder, "Encodes BC4 textures to a single-channel texture.");
bc4_decoder.def(py::init<uint8_t>(), py::arg("channel") = 3, R"doc(
__init__(channel : int = 3) -> None
Create a new BC4 decoder with the specified channel
bc4_decoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_decoder.def_property_readonly("channel", &BC4Decoder::GetChannel, "The channel to write to. 0 to 3 inclusive. Readonly.");
:param int channel: The channel that will be written to. 0 to 3 inclusive. Default: 3 (alpha).
)doc");
bc4_decoder.def_property_readonly("channel", &BC4Decoder::GetChannel, "The channel that will be written to. 0 to 3 inclusive. Readonly.");
}
} // namespace quicktex::bindings

@ -34,22 +34,42 @@ using namespace quicktex::s3tc;
using namespace quicktex::s3tc;
void InitBC5(py::module_ &s3tc) {
auto bc5 = s3tc.def_submodule("_bc5", "BC5 encoding/decoding module");
auto bc5 = s3tc.def_submodule("_bc5", "internal bc5 module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
py::options options;
options.disable_function_signatures();
// BC5Encoder
py::class_<BC5Encoder> bc5_encoder(bc5, "BC5Encoder", block_encoder);
py::class_<BC5Encoder> bc5_encoder(bc5, "BC5Encoder", block_encoder, "Encodes dual-channel textures to BC5.");
bc5_encoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1);
bc5_encoder.def_property_readonly("channels", &BC5Encoder::GetChannels);
bc5_encoder.def_property_readonly("bc4_decoders", &BC5Encoder::GetBC4Encoders);
bc5_encoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1, R"doc(
__init__(chan0 : int = 0, chan1 : int = 1) -> None
Create a new BC5 encoder with the specified channels
:param int chan0: the first channel that will be read from. 0 to 3 inclusive. Default: 0 (red).
:param int chan1: the second channel that will be read from. 0 to 3 inclusive. Default: 1 (green).
)doc");
bc5_encoder.def_property_readonly("channels", &BC5Encoder::GetChannels, "A 2-tuple of channels that will be read from. 0 to 3 inclusive. Readonly.");
bc5_encoder.def_property_readonly("bc4_encoders", &BC5Encoder::GetBC4Encoders,
"2-tuple of internal :py:class:`~quicktex.s3tc.bc4.BC4Encoder` s used for each channel. Readonly.");
// BC5Decoder
py::class_<BC5Decoder> bc5_decoder(bc5, "BC5Decoder", block_decoder);
py::class_<BC5Decoder> bc5_decoder(bc5, "BC5Decoder", block_decoder, "Decodes BC5 textures to a dual-channel texture.");
bc5_decoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1, R"doc(
__init__(chan0 : int = 0, chan1 : int = 1) -> None
Create a new BC5 decoder with the specified channels
:param int chan0: the first channel that will be written to. 0 to 3 inclusive. Default: 0 (red).
:param int chan1: the second channel that will be written to. 0 to 3 inclusive. Default: 1 (green).
)doc");
bc5_decoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1);
bc5_decoder.def_property_readonly("channels", &BC5Decoder::GetChannels);
bc5_decoder.def_property_readonly("bc4_decoders", &BC5Decoder::GetBC4Decoders);
bc5_decoder.def_property_readonly("channels", &BC5Decoder::GetChannels, "A 2-tuple of channels that will be written to. 0 to 3 inclusive. Readonly.");
bc5_decoder.def_property_readonly("bc4_decoders", &BC5Decoder::GetBC4Decoders,
"2-tuple of internal :py:class:`~quicktex.s3tc.bc4.BC4Decoder` s used for each channel. Readonly.");
}
} // namespace quicktex::bindings

@ -1 +1,3 @@
"""Classes representing various methods of interpolating BC1-3 blocks"""
from _quicktex._s3tc._interpolator import *

@ -31,7 +31,7 @@ using namespace quicktex::s3tc;
using InterpolatorPtr = std::shared_ptr<Interpolator>;
void InitInterpolator(py::module_ &s3tc) {
auto interpolator = s3tc.def_submodule("_interpolator", "Classes defining various methods of interpolating colors in BC1 and BC3 textures");
auto interpolator = s3tc.def_submodule("_interpolator", "Internal interpolator module");
// Interpolator
py::class_<Interpolator> ideal(

@ -95,7 +95,7 @@ class CMakeBuild(build_ext):
["cmake", ext.sourcedir] + cmake_args, cwd=self.build_temp
)
subprocess.check_call(
["cmake", "--build", "."] + build_args, cwd=self.build_temp
["cmake", "--build", ".", "--target", ext.name] + build_args, cwd=self.build_temp
)

Loading…
Cancel
Save