Skip to content

Commit

Permalink
(#9467) libvpx: fix Visual Studio 2022 build + modernize
Browse files Browse the repository at this point in the history
* modernize

* relocatable shared lib on macOS

* workaround for macOS M1 in test package

* disable whole optimization for msvc

* extend support for Visual Studio 2022 & Apple platforms

* libvpx has a C API

implementation is in C also, except one compilation unit in C++, so we keep compiler.libcxx & compiler.cppstd

* package proper lib if msvc & debug

also honor upstream lib name

* check CFLAGS to disable lto for msvc
  • Loading branch information
SpaceIm authored Mar 10, 2022
1 parent a776ca7 commit 1caa7f3
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 53 deletions.
22 changes: 15 additions & 7 deletions recipes/libvpx/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
sources:
"1.9.0":
url: "https://github.com/webmproject/libvpx/archive/v1.9.0.tar.gz"
sha256: "d279c10e4b9316bf11a570ba16c3d55791e1ad6faa4404c67422eb631782c80a"
"1.10.0":
url: "https://github.com/webmproject/libvpx/archive/v1.10.0.tar.gz"
sha256: "85803ccbdbdd7a3b03d930187cb055f1353596969c1f92ebec2db839fa4f834a"
"1.11.0":
url: "https://github.com/webmproject/libvpx/archive/v1.11.0.tar.gz"
sha256: "965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83"
"1.10.0":
url: "https://github.com/webmproject/libvpx/archive/v1.10.0.tar.gz"
sha256: "85803ccbdbdd7a3b03d930187cb055f1353596969c1f92ebec2db839fa4f834a"
"1.9.0":
url: "https://github.com/webmproject/libvpx/archive/v1.9.0.tar.gz"
sha256: "d279c10e4b9316bf11a570ba16c3d55791e1ad6faa4404c67422eb631782c80a"
patches:
"1.11.0":
- patch_file: "patches/0001-extended-support-1.10.0.patch"
base_path: "source_subfolder"
"1.10.0":
- patch_file: "patches/0001-extended-support-1.10.0.patch"
base_path: "source_subfolder"
"1.9.0":
- patch_file: "patches/msvc_conan_build.patch"
- patch_file: "patches/0001-extended-support-1.9.0.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-msvc_conan_build.patch"
base_path: "source_subfolder"
94 changes: 67 additions & 27 deletions recipes/libvpx/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from conan.tools.microsoft import msvc_runtime_flag
from conans import ConanFile, AutoToolsBuildEnvironment, tools
from conans.errors import ConanInvalidConfiguration
import os
import shutil
import re

required_conan_version = ">=1.33.0"
required_conan_version = ">=1.36.0"


class LibVPXConan(ConanFile):
Expand All @@ -29,13 +30,20 @@ class LibVPXConan(ConanFile):
options.update({name: [True, False] for name in _arch_options})
default_options.update({name: 'avx' not in name for name in _arch_options})

exports_sources = "patches/*"
_autotools = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _is_msvc(self):
return str(self.settings.compiler) in ["Visual Studio", "msvc"]

def export_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
self.copy(patch["patch_file"])

def config_options(self):
if self.settings.os == 'Windows':
del self.options.fPIC
Expand All @@ -50,7 +58,7 @@ def configure(self):
def validate(self):
if self.settings.os == "Windows" and self.options.shared:
raise ConanInvalidConfiguration("Windows shared builds are not supported")
if self.settings.compiler not in ["Visual Studio", "gcc", "clang", "apple-clang"]:
if str(self.settings.compiler) not in ["Visual Studio", "msvc", "gcc", "clang", "apple-clang"]:
raise ConanInvalidConfiguration("Unsupported compiler {}.".format(self.settings.compiler))
if self.settings.os == "Macos" and self.settings.arch == "armv8" and tools.Version(self.version) < "1.10.0":
raise ConanInvalidConfiguration("M1 only supported since 1.10, please upgrade")
Expand All @@ -68,6 +76,23 @@ def source(self):
tools.get(**self.conan_data["sources"][self.version],
destination=self._source_subfolder, strip_root=True)

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
# relocatable shared lib on macOS
tools.replace_in_file(os.path.join(self._source_subfolder, "build", "make", "Makefile"),
"-dynamiclib",
"-dynamiclib -install_name @rpath/$$(LIBVPX_SO)")
# Disable LTO for Visual Studio when CFLAGS doesn't contain -GL
if self._is_msvc:
lto = any(re.finditer("(^| )[/-]GL($| )", tools.get_env("CFLAGS", "")))
if not lto:
tools.replace_in_file(
os.path.join(self._source_subfolder, "build", "make", "gen_msvs_vcxproj.sh"),
"tag_content WholeProgramOptimization true",
"tag_content WholeProgramOptimization false",
)

def _configure_autotools(self):
if self._autotools:
return self._autotools
Expand All @@ -90,9 +115,8 @@ def _configure_autotools(self):
args.append('--enable-pic')
if self.settings.build_type == "Debug":
args.append('--enable-debug')
if self.settings.compiler == 'Visual Studio':
if 'MT' in str(self.settings.compiler.runtime):
args.append('--enable-static-msvcrt')
if self._is_msvc and "MT" in msvc_runtime_flag(self):
args.append('--enable-static-msvcrt')

arch = {'x86': 'x86',
'x86_64': 'x86_64',
Expand All @@ -101,10 +125,18 @@ def _configure_autotools(self):
'mips': 'mips32',
'mips64': 'mips64',
'sparc': 'sparc'}.get(str(self.settings.arch))
host_compiler = str(self.settings.compiler)
if host_compiler == 'Visual Studio':
compiler = 'vs' + str(self.settings.compiler.version)
elif host_compiler in ['gcc', 'clang', 'apple-clang']:
if self._is_msvc:
if self.settings.compiler == "Visual Studio":
vc_version = self.settings.compiler.version
else:
vc_version = {
"190": "14",
"191": "15",
"192": "16",
"193": "17",
}[str(self.settings.compiler.version)]
compiler = "vs{}".format(vc_version)
elif self.settings.compiler in ["gcc", "clang", "apple-clang"]:
compiler = 'gcc'

host_os = str(self.settings.os)
Expand All @@ -130,9 +162,9 @@ def _configure_autotools(self):
for name in self._arch_options:
if not self.options.get_safe(name):
args.append('--disable-%s' % name)
with tools.vcvars(self.settings) if self.settings.compiler == 'Visual Studio' else tools.no_op():
with tools.vcvars(self.settings) if self._is_msvc else tools.no_op():
self._autotools = AutoToolsBuildEnvironment(self, win_bash=win_bash)
if self.settings.compiler == "Visual Studio":
if self._is_msvc:
# gen_msvs_vcxproj.sh doesn't like custom flags
self._autotools.cxxflags = []
self._autotools.flags = []
Expand All @@ -143,27 +175,35 @@ def _configure_autotools(self):
return self._autotools

def build(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
with tools.vcvars(self.settings) if self.settings.compiler == "Visual Studio" else tools.no_op():
self._patch_sources()
with tools.vcvars(self.settings) if self._is_msvc else tools.no_op():
autotools = self._configure_autotools()
autotools.make()

def package(self):
with tools.vcvars(self.settings) if self.settings.compiler == "Visual Studio" else tools.no_op():
self.copy(pattern="LICENSE", src=self._source_subfolder, dst="licenses")
with tools.vcvars(self.settings) if self._is_msvc else tools.no_op():
autotools = self._configure_autotools()
autotools.install()
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))

self.copy(pattern="LICENSE", src=self._source_subfolder, dst='licenses')
if self.settings.os == 'Windows' and self.settings.compiler == 'Visual Studio':
name = 'vpxmt.lib' if 'MT' in str(self.settings.compiler.runtime) else 'vpxmd.lib'
if self.settings.arch == 'x86_64':
libdir = os.path.join(self.package_folder, 'lib', 'x64')
elif self.settings.arch == 'x86':
libdir = os.path.join(self.package_folder, 'lib', 'Win32')
shutil.move(os.path.join(libdir, name), os.path.join(self.package_folder, 'lib', 'vpx.lib'))
tools.rmdir(os.path.join(self.package_folder, 'lib', 'pkgconfig'))
if self._is_msvc:
# don't trust install target
tools.rmdir(os.path.join(self.package_folder, "lib"))
libdir = os.path.join(
"Win32" if self.settings.arch == "x86" else "x64",
"Debug" if self.settings.build_type == "Debug" else "Release",
)
self.copy("vpx*.lib", src=libdir, dst="lib")

def package_info(self):
self.cpp_info.set_property("pkg_config_name", "vpx")
suffix = msvc_runtime_flag(self).lower() if self._is_msvc else ""
self.cpp_info.libs = [f"vpx{suffix}"]
if not self.options.shared:
libcxx = tools.stdcpp_library(self)
if libcxx:
self.cpp_info.system_libs.append(libcxx)

# TODO: to remove in conan v2 once pkg_config generator removed
self.cpp_info.names["pkg_config"] = "vpx"
self.cpp_info.libs = ["vpx"]
98 changes: 98 additions & 0 deletions recipes/libvpx/all/patches/0001-extended-support-1.10.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -774,7 +774,7 @@ process_common_toolchain() {
tgt_isa=x86_64
tgt_os=`echo $gcctarget | sed 's/.*\(darwin1[0-9]\).*/\1/'`
;;
- *darwin20*)
+ *darwin2[0-1]*)
tgt_isa=`uname -m`
tgt_os=`echo $gcctarget | sed 's/.*\(darwin2[0-9]\).*/\1/'`
;;
@@ -918,9 +918,9 @@ process_common_toolchain() {
add_cflags "-mmacosx-version-min=10.15"
add_ldflags "-mmacosx-version-min=10.15"
;;
- *-darwin20-*)
- add_cflags "-mmacosx-version-min=10.16 -arch ${toolchain%%-*}"
- add_ldflags "-mmacosx-version-min=10.16 -arch ${toolchain%%-*}"
+ *-darwin2[0-1]-*)
+ add_cflags "-arch ${toolchain%%-*}"
+ add_ldflags "-arch ${toolchain%%-*}"
;;
*-iphonesimulator-*)
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
--- a/build/make/gen_msvs_sln.sh
+++ b/build/make/gen_msvs_sln.sh
@@ -219,6 +219,7 @@ for opt in "$@"; do
14) vs_year=2015 ;;
15) vs_year=2017 ;;
16) vs_year=2019 ;;
+ 17) vs_year=2022 ;;
*) die Unrecognized Visual Studio Version in $opt ;;
esac
;;
@@ -232,7 +233,7 @@ done
outfile=${outfile:-/dev/stdout}
mkoutfile=${mkoutfile:-/dev/stdout}
case "${vs_ver}" in
- 1[4-6])
+ 1[4-7])
# VS has used Format Version 12.00 continuously since vs11.
sln_vers="12.00"
sln_vers_str="Visual Studio ${vs_year}"
--- a/build/make/gen_msvs_vcxproj.sh
+++ b/build/make/gen_msvs_vcxproj.sh
@@ -170,7 +170,7 @@ for opt in "$@"; do
--ver=*)
vs_ver="$optval"
case "$optval" in
- 1[4-6])
+ 1[4-7])
;;
*) die Unrecognized Visual Studio Version in $opt
;;
@@ -344,6 +344,9 @@ generate_vcxproj() {
if [ "$vs_ver" = "16" ]; then
tag_content PlatformToolset v142
fi
+ if [ "$vs_ver" = "17" ]; then
+ tag_content PlatformToolset v143
+ fi
tag_content CharacterSet Unicode
if [ "$config" = "Release" ]; then
tag_content WholeProgramOptimization true
--- a/configure
+++ b/configure
@@ -100,6 +100,7 @@ EOF
all_platforms="${all_platforms} arm64-android-gcc"
all_platforms="${all_platforms} arm64-darwin-gcc"
all_platforms="${all_platforms} arm64-darwin20-gcc"
+all_platforms="${all_platforms} arm64-darwin21-gcc"
all_platforms="${all_platforms} arm64-linux-gcc"
all_platforms="${all_platforms} arm64-win64-gcc"
all_platforms="${all_platforms} arm64-win64-vs15"
@@ -139,6 +140,7 @@ all_platforms="${all_platforms} x86-win32-gcc"
all_platforms="${all_platforms} x86-win32-vs14"
all_platforms="${all_platforms} x86-win32-vs15"
all_platforms="${all_platforms} x86-win32-vs16"
+all_platforms="${all_platforms} x86-win32-vs17"
all_platforms="${all_platforms} x86_64-android-gcc"
all_platforms="${all_platforms} x86_64-darwin9-gcc"
all_platforms="${all_platforms} x86_64-darwin10-gcc"
@@ -152,6 +154,7 @@ all_platforms="${all_platforms} x86_64-darwin17-gcc"
all_platforms="${all_platforms} x86_64-darwin18-gcc"
all_platforms="${all_platforms} x86_64-darwin19-gcc"
all_platforms="${all_platforms} x86_64-darwin20-gcc"
+all_platforms="${all_platforms} x86_64-darwin21-gcc"
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
@@ -160,6 +163,7 @@ all_platforms="${all_platforms} x86_64-win64-gcc"
all_platforms="${all_platforms} x86_64-win64-vs14"
all_platforms="${all_platforms} x86_64-win64-vs15"
all_platforms="${all_platforms} x86_64-win64-vs16"
+all_platforms="${all_platforms} x86_64-win64-vs17"
all_platforms="${all_platforms} generic-gnu"

# all_targets is a list of all targets that can be configured
58 changes: 58 additions & 0 deletions recipes/libvpx/all/patches/0001-extended-support-1.9.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
--- a/build/make/gen_msvs_sln.sh
+++ b/build/make/gen_msvs_sln.sh
@@ -219,6 +219,7 @@ for opt in "$@"; do
14) vs_year=2015 ;;
15) vs_year=2017 ;;
16) vs_year=2019 ;;
+ 17) vs_year=2022 ;;
*) die Unrecognized Visual Studio Version in $opt ;;
esac
;;
@@ -232,7 +233,7 @@ done
outfile=${outfile:-/dev/stdout}
mkoutfile=${mkoutfile:-/dev/stdout}
case "${vs_ver}" in
- 1[4-6])
+ 1[4-7])
# VS has used Format Version 12.00 continuously since vs11.
sln_vers="12.00"
sln_vers_str="Visual Studio ${vs_year}"
--- a/build/make/gen_msvs_vcxproj.sh
+++ b/build/make/gen_msvs_vcxproj.sh
@@ -168,7 +168,7 @@ for opt in "$@"; do
--ver=*)
vs_ver="$optval"
case "$optval" in
- 1[4-6])
+ 1[4-7])
;;
*) die Unrecognized Visual Studio Version in $opt
;;
@@ -342,6 +342,9 @@ generate_vcxproj() {
if [ "$vs_ver" = "16" ]; then
tag_content PlatformToolset v142
fi
+ if [ "$vs_ver" = "17" ]; then
+ tag_content PlatformToolset v143
+ fi
tag_content CharacterSet Unicode
if [ "$config" = "Release" ]; then
tag_content WholeProgramOptimization true
--- a/configure
+++ b/configure
@@ -138,6 +138,7 @@ all_platforms="${all_platforms} x86-win32-gcc"
all_platforms="${all_platforms} x86-win32-vs14"
all_platforms="${all_platforms} x86-win32-vs15"
all_platforms="${all_platforms} x86-win32-vs16"
+all_platforms="${all_platforms} x86-win32-vs17"
all_platforms="${all_platforms} x86_64-android-gcc"
all_platforms="${all_platforms} x86_64-darwin9-gcc"
all_platforms="${all_platforms} x86_64-darwin10-gcc"
@@ -158,6 +159,7 @@ all_platforms="${all_platforms} x86_64-win64-gcc"
all_platforms="${all_platforms} x86_64-win64-vs14"
all_platforms="${all_platforms} x86_64-win64-vs15"
all_platforms="${all_platforms} x86_64-win64-vs16"
+all_platforms="${all_platforms} x86_64-win64-vs17"
all_platforms="${all_platforms} generic-gnu"

# all_targets is a list of all targets that can be configured
11 changes: 6 additions & 5 deletions recipes/libvpx/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 3.1)
project(test_package)

project(test_package C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
conan_basic_setup(TARGETS)

find_package(libvpx REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} libvpx::libvpx)
13 changes: 11 additions & 2 deletions recipes/libvpx/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@


class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
settings = "os", "arch", "compiler", "build_type"
generators = "cmake", "cmake_find_package_multi"

def build_requirements(self):
if self.settings.os == "Macos" and self.settings.arch == "armv8":
# Workaround for CMake bug with error message:
# Attempting to use @rpath without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being
# set. This could be because you are using a Mac OS X version less than 10.5
# or because CMake's platform configuration is corrupt.
# FIXME: Remove once CMake on macOS/M1 CI runners is upgraded.
self.build_requires("cmake/3.22.0")

def build(self):
cmake = CMake(self)
Expand Down
9 changes: 9 additions & 0 deletions recipes/libvpx/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <vpx/vpx_codec.h>

#include <stdio.h>

int main()
{
printf("vpx version %s\n", vpx_codec_version_str());
return 0;
}
Loading

0 comments on commit 1caa7f3

Please sign in to comment.