-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ffmpeg: conan v2 support #15819
ffmpeg: conan v2 support #15819
Changes from 6 commits
e2a924a
e992a74
8b79edb
1ad6773
d6a263b
6fad507
a94f2d9
584f517
946f37c
fd1ed38
5f0359f
69a3141
139aafd
24395f1
18f521d
1b244ee
de0f80a
1cfddba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,18 @@ | ||
from conan import ConanFile | ||
from conan.errors import ConanInvalidConfiguration | ||
from conan.tools.apple import is_apple_os, to_apple_arch | ||
from conan.tools.apple import is_apple_os | ||
from conan.tools.build import cross_building | ||
from conan.tools.env import VirtualBuildEnv, VirtualRunEnv | ||
from conan.tools.files import ( | ||
apply_conandata_patches, chdir, export_conandata_patches, get, rename, | ||
apply_conandata_patches, chdir, copy, export_conandata_patches, get, rename, | ||
replace_in_file, rm, rmdir | ||
) | ||
from conan.tools.microsoft import check_min_vs, is_msvc | ||
from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain, PkgConfigDeps | ||
from conan.tools.layout import basic_layout | ||
from conan.tools.microsoft import check_min_vs, is_msvc, unix_path | ||
from conan.tools.scm import Version | ||
from conans import AutoToolsBuildEnvironment, tools | ||
from conans.tools import get_gnu_triplet | ||
import os | ||
import contextlib | ||
import glob | ||
import shutil | ||
import re | ||
|
@@ -184,13 +186,6 @@ class FFMpegConan(ConanFile): | |
"enable_filters": None, | ||
} | ||
|
||
generators = "pkg_config" | ||
_autotools = None | ||
|
||
@property | ||
def _source_subfolder(self): | ||
return "source_subfolder" | ||
|
||
@property | ||
def _settings_build(self): | ||
return getattr(self, "settings_build", self.settings) | ||
|
@@ -258,6 +253,9 @@ def configure(self): | |
self.settings.rm_safe("compiler.cppstd") | ||
self.settings.rm_safe("compiler.libcxx") | ||
|
||
def layout(self): | ||
basic_layout(self, src_folder="src") | ||
|
||
def requirements(self): | ||
if self.options.with_zlib: | ||
self.requires("zlib/1.2.13") | ||
|
@@ -325,18 +323,20 @@ def validate(self): | |
|
||
def build_requirements(self): | ||
if self.settings.arch in ("x86", "x86_64"): | ||
self.build_requires("yasm/1.3.0") | ||
self.build_requires("pkgconf/1.9.3") | ||
if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"): | ||
self.build_requires("msys2/cci.latest") | ||
self.tool_requires("yasm/1.3.0") | ||
if not self.conf.get("tools.gnu:pkg_config", check_type=str): | ||
self.tool_requires("pkgconf/1.9.3") | ||
if self._settings_build.os == "Windows": | ||
self.win_bash = True | ||
if not self.conf.get("tools.microsoft.bash:path", check_type=str): | ||
self.tool_requires("msys2/cci.latest") | ||
|
||
def source(self): | ||
get(self, **self.conan_data["sources"][self.version], | ||
destination=self._source_subfolder, strip_root=True) | ||
get(self, **self.conan_data["sources"][self.version], strip_root=True) | ||
|
||
@property | ||
def _target_arch(self): | ||
triplet = tools.get_gnu_triplet( | ||
triplet = get_gnu_triplet( | ||
"Macos" if is_apple_os(self) else str(self.settings.os), | ||
str(self.settings.arch), | ||
str(self.settings.compiler) if self.settings.os == "Windows" else None, | ||
|
@@ -349,7 +349,7 @@ def _target_os(self): | |
if is_msvc(self): | ||
return "win32" | ||
else: | ||
triplet = tools.get_gnu_triplet( | ||
triplet = get_gnu_triplet( | ||
"Macos" if is_apple_os(self) else str(self.settings.os), | ||
str(self.settings.arch), | ||
str(self.settings.compiler) if self.settings.os == "Windows" else None, | ||
|
@@ -363,35 +363,28 @@ def _target_os(self): | |
|
||
def _patch_sources(self): | ||
apply_conandata_patches(self) | ||
if is_msvc(self) and self.options.with_libx264 and not self.dependencies["libx264"].options.shared and Version(self.version) <= "5.0": | ||
if is_msvc(self) and self.options.with_libx264 and not self.dependencies["libx264"].options.shared: | ||
# suppress MSVC linker warnings: https://trac.ffmpeg.org/ticket/7396 | ||
# warning LNK4049: locally defined symbol x264_levels imported | ||
# warning LNK4049: locally defined symbol x264_bit_depth imported | ||
replace_in_file(self, os.path.join(self.source_folder, self._source_subfolder, "libavcodec", "libx264.c"), | ||
replace_in_file(self, os.path.join(self.source_folder, "libavcodec", "libx264.c"), | ||
"#define X264_API_IMPORTS 1", "") | ||
if self.options.with_ssl == "openssl": | ||
# https://trac.ffmpeg.org/ticket/5675 | ||
openssl_libraries = " ".join( | ||
[f"-l{lib}" for lib in self.dependencies["openssl"].cpp_info.aggregated_components().libs]) | ||
replace_in_file(self, os.path.join(self.source_folder, self._source_subfolder, "configure"), | ||
replace_in_file(self, os.path.join(self.source_folder, "configure"), | ||
"check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||", | ||
f"check_lib openssl openssl/ssl.h OPENSSL_init_ssl {openssl_libraries} || ") | ||
|
||
@contextlib.contextmanager | ||
def _build_context(self): | ||
with tools.environment_append({"PKG_CONFIG_PATH": tools.unix_path(self.build_folder)}): | ||
if is_msvc(self): | ||
with tools.vcvars(self): | ||
yield | ||
else: | ||
yield | ||
replace_in_file(self, os.path.join(self.source_folder, "configure"), "echo libx264.lib", "echo x264.lib") | ||
|
||
def _configure_autotools(self): | ||
if self._autotools: | ||
return self._autotools | ||
self._autotools = AutoToolsBuildEnvironment( | ||
self, win_bash=tools.os_info.is_windows) | ||
self._autotools.libs = [] | ||
def generate(self): | ||
env = VirtualBuildEnv(self) | ||
env.generate() | ||
if not cross_building(self): | ||
env = VirtualRunEnv(self) | ||
env.generate(scope="build") | ||
|
||
def opt_enable_disable(what, v): | ||
return "--{}-{}".format("enable" if v else "disable", what) | ||
|
@@ -400,6 +393,7 @@ def opt_append_disable_if_set(args, what, v): | |
if v: | ||
args.append(f"--disable-{what}") | ||
|
||
tc = AutotoolsToolchain(self) | ||
args = [ | ||
"--pkg-config-flags=--static", | ||
"--disable-doc", | ||
|
@@ -543,57 +537,57 @@ def opt_append_disable_if_set(args, what, v): | |
]) | ||
if not self.options.with_programs: | ||
args.append("--disable-programs") | ||
# since ffmpeg's build system ignores toolchain variables | ||
if tools.get_env("AR"): | ||
args.append("--ar={}".format(tools.get_env("AR"))) | ||
if tools.get_env("AS") and self.options.with_asm: | ||
args.append("--as={}".format(tools.get_env("AS"))) | ||
if tools.get_env("CC"): | ||
args.append("--cc={}".format(tools.get_env("CC"))) | ||
if tools.get_env("CXX"): | ||
args.append("--cxx={}".format(tools.get_env("CXX"))) | ||
if tools.get_env("NM"): | ||
args.append("--nm={}".format(tools.get_env("NM"))) | ||
if tools.get_env("RANLIB"): | ||
args.append("--ranlib={}".format(tools.get_env("RANLIB"))) | ||
if tools.get_env("STRIP"): | ||
args.append("--strip={}".format(tools.get_env("STRIP"))) | ||
extra_cflags = [] | ||
extra_ldflags = [] | ||
if is_apple_os(self) and self.settings.os.version: | ||
extra_cflags.append(tools.apple_deployment_target_flag( | ||
self.settings.os, self.settings.os.version)) | ||
extra_ldflags.append(tools.apple_deployment_target_flag( | ||
self.settings.os, self.settings.os.version)) | ||
# since ffmpeg"s build system ignores CC and CXX | ||
compilers_from_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) | ||
buildenv_vars = VirtualBuildEnv(self).vars() | ||
asm = compilers_from_conf.get("asm", buildenv_vars.get("AS")) | ||
if asm: | ||
args.append(f"--as={unix_path(self, asm)}") | ||
cc = compilers_from_conf.get("c", buildenv_vars.get("CC")) | ||
if cc: | ||
args.append(f"--cc={unix_path(self, cc)}") | ||
cxx = compilers_from_conf.get("cpp", buildenv_vars.get("CC")) | ||
if cxx: | ||
args.append(f"--cxx={unix_path(self, cxx)}") | ||
pkg_config = self.conf.get("tools.gnu:pkg_config", default=buildenv_vars.get("PKG_CONFIG"), check_type=str) | ||
if pkg_config: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the flags for ar, nm, ranlib and strip are missing. This might cause some issues while cross compiling. At least it was an issue with conan1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 5f0359f |
||
args.append(f"--pkg-config={unix_path(self, pkg_config)}") | ||
if is_msvc(self): | ||
args.append("--pkg-config={}".format(tools.get_env("PKG_CONFIG"))) | ||
args.append("--toolchain=msvc") | ||
if not check_min_vs(self, "190", raise_invalid=False): | ||
# Visual Studio 2013 (and earlier) doesn't support "inline" keyword for C (only for C++) | ||
self._autotools.defines.append("inline=__inline") | ||
tc.extra_defines.append("inline=__inline") | ||
if cross_building(self): | ||
if self._target_os == "emscripten": | ||
args.append("--target-os=none") | ||
else: | ||
args.append("--target-os={}".format(self._target_os)) | ||
|
||
args.append(f"--target-os={self._target_os}") | ||
if is_apple_os(self): | ||
if self.options.with_audiotoolbox: | ||
args.append("--disable-outdev=audiotoolbox") | ||
|
||
xcrun = tools.XCRun(self.settings) | ||
apple_arch = to_apple_arch(self) | ||
extra_cflags.extend( | ||
["-arch {}".format(apple_arch), "-isysroot {}".format(xcrun.sdk_path)]) | ||
extra_ldflags.extend( | ||
["-arch {}".format(apple_arch), "-isysroot {}".format(xcrun.sdk_path)]) | ||
|
||
args.append("--extra-cflags={}".format(" ".join(extra_cflags))) | ||
args.append("--extra-ldflags={}".format(" ".join(extra_ldflags))) | ||
|
||
self._autotools.configure( | ||
args=args, configure_dir=self._source_subfolder, build=False, host=False, target=False) | ||
return self._autotools | ||
args.append("--extra-cflags={}".format(" ".join(tc.cflags))) | ||
SpaceIm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
args.append("--extra-ldflags={}".format(" ".join(tc.ldflags))) | ||
SpaceIm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
tc.configure_args.extend(args) | ||
# Custom configure script of ffmpeg understands: | ||
# --prefix, --bindir, --datadir, --docdir, --incdir, --libdir, --mandir | ||
# Options --datadir, --docdir, --incdir, and --mandir are not injected by AutotoolsToolchain but their default value | ||
# in ffmpeg script matches expected conan install layout. | ||
# Several options injected by AutotoolsToolchain are unknown from this configure script and must be pruned: | ||
tc.update_configure_args({ | ||
"--sbindir": None, | ||
"--includedir": None, | ||
"--oldincludedir": None, | ||
"--datarootdir": None, | ||
"--build": None, | ||
"--host": None, | ||
"--target": None, | ||
}) | ||
tc.generate() | ||
|
||
deps = AutotoolsDeps(self) | ||
deps.generate() | ||
deps = PkgConfigDeps(self) | ||
deps.generate() | ||
|
||
def _split_and_format_options_string(self, flag_name, options_list): | ||
if not options_list: | ||
|
@@ -610,23 +604,20 @@ def _split_options_string(options_string): | |
|
||
def build(self): | ||
self._patch_sources() | ||
replace_in_file(self, os.path.join(self.source_folder, self._source_subfolder, "configure"), | ||
"echo libx264.lib", "echo x264.lib") | ||
if self.options.with_libx264: | ||
shutil.copy("x264.pc", "libx264.pc") | ||
with self._build_context(): | ||
autotools = self._configure_autotools() | ||
autotools.make() | ||
# ffmepg expects libx264.pc instead of x264.pc | ||
with chdir(self, self.generators_folder): | ||
shutil.copy("x264.pc", "libx264.pc") | ||
autotools = Autotools(self) | ||
autotools.configure() | ||
autotools.make() | ||
|
||
def package(self): | ||
self.copy("LICENSE.md", dst="licenses", src=self._source_subfolder) | ||
with self._build_context(): | ||
autotools = self._configure_autotools() | ||
autotools.install() | ||
|
||
copy(self, "LICENSE.md", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) | ||
autotools = Autotools(self) | ||
autotools.install() | ||
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) | ||
rmdir(self, os.path.join(self.package_folder, "share")) | ||
|
||
if is_msvc(self): | ||
if self.options.shared: | ||
# ffmpeg created `.lib` files in the `/bin` folder | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not allowed by conancenter to import internal conan functions