libx264/cci.20220602

x264 is a free software library and application for encoding video streams into the H.264/MPEG-4 AVC compression format
GPL-2.0
License
cci.20220602
Version
2,845
Downloads
Loading...
Loading...
1
from conan.tools.files import rename
2
from conans import ConanFile, tools, AutoToolsBuildEnvironment
3
import contextlib
4
import os
5
6
required_conan_version = ">=1.38.0"
7
8
9
class LibX264Conan(ConanFile):
10
    name = "libx264"
11
    url = "https://github.com/conan-io/conan-center-index"
12
    homepage = "https://www.videolan.org/developers/x264.html"
13
    description = "x264 is a free software library and application for encoding video streams into the " \
14
                  "H.264/MPEG-4 AVC compression format"
15
    topics = ("libx264", "video", "encoding")
16
    license = "GPL-2.0"
17
18
    settings = "os", "arch", "compiler", "build_type"
19
    options = {
20
        "shared": [True, False],
21
        "fPIC": [True, False],
22
        "bit_depth": [8, 10, "all"],
23
    }
24
    default_options = {
25
        "shared": False,
26
        "fPIC": True,
27
        "bit_depth": "all",
28
    }
29
30
    _autotools = None
31
    _override_env = {}
32
33
    @property
34
    def _is_msvc(self):
35
        return str(self.settings.compiler) in ["Visual Studio", "msvc"]
36
37
    @property
38
    def _source_subfolder(self):
39
        return "source_subfolder"
40
41
    @property
42
    def _settings_build(self):
43
        return getattr(self, "settings_build", self.settings)
44
45
    def config_options(self):
46
        if self.settings.os == "Windows":
47
            del self.options.fPIC
48
49
    def configure(self):
50
        if self.options.shared:
51
            del self.options.fPIC
52
        del self.settings.compiler.libcxx
53
        del self.settings.compiler.cppstd
54
55
    @property
56
    def _with_nasm(self):
57
        return self.settings.arch in ("x86", "x86_64")
58
59
    def build_requirements(self):
60
        if self._with_nasm:
61
            self.build_requires("nasm/2.15.05")
62
        if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"):
63
            self.build_requires("msys2/cci.latest")
64
65
    def source(self):
66
        tools.get(**self.conan_data["sources"][self.version],
67
                  destination=self._source_subfolder, strip_root=True)
68
69
    @contextlib.contextmanager
70
    def _build_context(self):
71
        with tools.vcvars(self) if self._is_msvc else tools.no_op():
72
            yield
73
74
    @property
75
    def env(self):
76
        ret = super(LibX264Conan, self).env
77
        ret.update(self._override_env)
78
        return ret
79
80
    def _configure_autotools(self):
81
        if self._autotools:
82
            return self._autotools
83
        self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows)
84
        self._autotools.libs = []
85
        extra_asflags = []
86
        extra_cflags = []
87
        extra_ldflags = []
88
        args = [
89
            "--bit-depth=%s" % str(self.options.bit_depth),
90
            "--disable-cli",
91
            "--prefix={}".format(tools.unix_path(self.package_folder)),
92
        ]
93
        if self.options.shared:
94
            args.append("--enable-shared")
95
        else:
96
            args.append("--enable-static")
97
        if self.options.get_safe("fPIC", self.settings.os != "Windows"):
98
            args.append("--enable-pic")
99
        if self.settings.build_type == "Debug":
100
            args.append("--enable-debug")
101
        if self.settings.os == "Macos" and self.settings.arch == "armv8":
102
            # bitstream-a.S:29:18: error: unknown token in expression
103
            extra_asflags.append("-arch arm64")
104
            extra_ldflags.append("-arch arm64")
105
            args.append("--host=aarch64-apple-darwin")
106
107
        if self._with_nasm:
108
            # FIXME: get using user_build_info
109
            self._override_env["AS"] = os.path.join(self.dependencies.build["nasm"].package_folder, "bin", "nasm{}".format(".exe" if tools.os_info.is_windows else "")).replace("\\", "/")
110
        if tools.cross_building(self):
111
            if self.settings.os == "Android":
112
                # the as of ndk does not work well for building libx264
113
                self._override_env["AS"] = os.environ["CC"]
114
                ndk_root = tools.unix_path(os.environ["NDK_ROOT"])
115
                arch = {
116
                    "armv7": "arm",
117
                    "armv8": "aarch64",
118
                    "x86": "i686",
119
                    "x86_64": "x86_64",
120
                }.get(str(self.settings.arch))
121
                abi = "androideabi" if self.settings.arch == "armv7" else "android"
122
                args.append("--cross-prefix={}".format("{}/bin/{}-linux-{}-".format(ndk_root, arch, abi)))
123
        if self._is_msvc:
124
            self._override_env["CC"] = "cl -nologo"
125
            extra_cflags.extend(self._autotools.flags)
126
            if not (self.settings.compiler == "Visual Studio" and tools.Version(self.settings.compiler.version) < "12"):
127
                extra_cflags.append("-FS")
128
        build_canonical_name = None
129
        host_canonical_name = None
130
        if self._is_msvc:
131
            # autotools does not know about the msvc canonical name(s)
132
            build_canonical_name = False
133
            host_canonical_name = False
134
        if extra_asflags:
135
            args.append("--extra-asflags={}".format(" ".join(extra_asflags)))
136
        if extra_cflags:
137
            args.append("--extra-cflags={}".format(" ".join(extra_cflags)))
138
        if extra_ldflags:
139
            args.append("--extra-ldflags={}".format(" ".join(extra_ldflags)))
140
        self._autotools.configure(args=args, vars=self._override_env, configure_dir=self._source_subfolder, build=build_canonical_name, host=host_canonical_name)
141
        return self._autotools
142
143
    def build(self):
144
        with self._build_context():
145
            # relocatable shared lib on macOS
146
            tools.replace_in_file(os.path.join(self._source_subfolder, "configure"),
147
                                  "-install_name \\$(DESTDIR)\\$(libdir)/",
148
                                  "-install_name @rpath/")
149
            autotools = self._configure_autotools()
150
            autotools.make()
151
152
    def package(self):
153
        self.copy(pattern="COPYING", src=self._source_subfolder, dst="licenses")
154
        with self._build_context():
155
            autotools = self._configure_autotools()
156
            autotools.install()
157
        tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
158
        if self._is_msvc:
159
            ext = ".dll.lib" if self.options.shared else ".lib"
160
            rename(self, os.path.join(self.package_folder, "lib", "libx264{}".format(ext)),
161
                         os.path.join(self.package_folder, "lib", "x264.lib"))
162
163
    def package_info(self):
164
        self.cpp_info.set_property("pkg_config_name", "x264")
165
        self.cpp_info.libs = ["x264"]
166
        if self._is_msvc and self.options.shared:
167
            self.cpp_info.defines.append("X264_API_IMPORTS")
168
        if self.settings.os in ("FreeBSD", "Linux"):
169
            self.cpp_info.system_libs.extend(["dl", "pthread", "m"])
170
        elif self.settings.os == "Android":
171
            self.cpp_info.system_libs.extend(["dl", "m"])
172
173
        # TODO: to remove in conan v2 once pkg_config generator removed
174
        self.cpp_info.names["pkg_config"] = "x264"
175
176