Skip to content

Commit

Permalink
[fontconfig] use new meson toolchain where supported
Browse files Browse the repository at this point in the history
  • Loading branch information
planetmarshall committed Oct 28, 2022
1 parent 1022097 commit 067da2d
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 63 deletions.
7 changes: 0 additions & 7 deletions recipes/fontconfig/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
sources:
"2.13.93":
url: "https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.93.tar.gz"
sha256: "0f302a18ee52dde0793fe38b266bf269dfe6e0c0ae140e30d72c6cca5dc08db5"
"2.13.92":
url: "https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.92.tar.gz"
sha256: "3406a05b83a42231e3df68d02bc0a0cf47b3f2e8f11c8ede62267daf5f130016"
"2.13.91":
url: "https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.91.tar.gz"
sha256: "19e5b1bc9d013a52063a44e1307629711f0bfef35b9aca16f9c793971e2eb1e5"
patches:
"2.13.93":
- patch_file: "patches/0001-meson-win32.patch"
base_path: "source_subfolder"
71 changes: 16 additions & 55 deletions recipes/fontconfig/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools import files, scm, microsoft
from conans import tools, AutoToolsBuildEnvironment, Meson
from conans import tools, AutoToolsBuildEnvironment
import contextlib
import functools
import os
Expand Down Expand Up @@ -61,15 +61,13 @@ def requirements(self):
self.requires("libuuid/1.0.3")

def validate(self):
if microsoft.is_msvc(self) and scm.Version(self.version) < "2.13.93":
if microsoft.is_msvc(self):
raise ConanInvalidConfiguration("fontconfig does not support Visual Studio for versions < 2.13.93.")

def build_requirements(self):
self.build_requires("gperf/3.1")
self.build_requires("pkgconf/1.7.4")
if microsoft.is_msvc(self):
self.build_requires("meson/0.63.1")
elif self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"):
if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"):
self.build_requires("msys2/cci.latest")

def source(self):
Expand All @@ -94,16 +92,6 @@ def _configure_autotools(self):
files.replace_in_file(self, "Makefile", "po-conf test", "po-conf")
return autotools

@functools.lru_cache(1)
def _configure_meson(self):
meson = Meson(self)
meson.options["doc"] = "disabled"
meson.options["nls"] = "disabled"
meson.options["tests"] = "disabled"
meson.options["tools"] = "disabled"
meson.configure(source_folder=self._source_subfolder, build_folder=self._build_subfolder)
return meson

def _patch_files(self):
files.apply_conandata_patches(self)
# fontconfig requires libtool version number, change it for the corresponding freetype one
Expand All @@ -117,51 +105,24 @@ def _patch_files(self):
"RUN_FC_CACHE_TEST=false"
)

@contextlib.contextmanager
def _build_context(self):
if microsoft.is_msvc(self):
with tools.vcvars(self):
env = {
"CC": "cl",
"CXX": "cl",
"LD": "link",
"AR": "lib",
}
with tools.environment_append(env):
yield
else:
yield

def build(self):
self._patch_files()
if microsoft.is_msvc(self):
with self._build_context():
meson = self._configure_meson()
meson.build()
else:
# relocatable shared lib on macOS
files.replace_in_file(self,
os.path.join(self._source_subfolder, "configure"),
"-install_name \\$rpath/",
"-install_name @rpath/"
)
with tools.run_environment(self):
autotools = self._configure_autotools()
autotools.make()
# relocatable shared lib on macOS
files.replace_in_file(self,
os.path.join(self._source_subfolder, "configure"),
"-install_name \\$rpath/",
"-install_name @rpath/"
)
with tools.run_environment(self):
autotools = self._configure_autotools()
autotools.make()

def package(self):
self.copy("COPYING", src=self._source_subfolder, dst="licenses")
if microsoft.is_msvc(self):
with self._build_context():
meson = self._configure_meson()
meson.install()
if os.path.isfile(os.path.join(self.package_folder, "lib", "libfontconfig.a")):
files.rename(self, os.path.join(self.package_folder, "lib", "libfontconfig.a"),
os.path.join(self.package_folder, "lib", "fontconfig.lib"))
else:
with tools.run_environment(self):
autotools = self._configure_autotools()
autotools.install()
with tools.run_environment(self):
autotools = self._configure_autotools()
autotools.install()

files.rm(self, "*.pdb", os.path.join(self.package_folder, "bin"))
files.rm(self, "*.conf", os.path.join(self.package_folder, "bin", "etc", "fonts", "conf.d"))
files.rm(self, "*.def", os.path.join(self.package_folder, "lib"))
Expand Down
2 changes: 1 addition & 1 deletion recipes/fontconfig/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
versions:
"2.13.93":
folder: all
folder: meson
"2.13.92":
folder: all
"2.13.91":
Expand Down
7 changes: 7 additions & 0 deletions recipes/fontconfig/meson/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sources:
"2.13.93":
url: "https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.93.tar.gz"
sha256: "0f302a18ee52dde0793fe38b266bf269dfe6e0c0ae140e30d72c6cca5dc08db5"
patches:
"2.13.93":
- patch_file: "patches/0001-meson-win32.patch"
145 changes: 145 additions & 0 deletions recipes/fontconfig/meson/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.files import (
apply_conandata_patches,
copy,
export_conandata_patches,
get,
rename,
replace_in_file,
rm,
rmdir
)
from conan.tools.layout import basic_layout
from conan.tools.microsoft import is_msvc
from conan.tools.scm import Version
from conan.tools.env import VirtualBuildEnv
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.gnu import PkgConfigDeps

import os

required_conan_version = ">=1.52.0"


class FontconfigConan(ConanFile):
name = "fontconfig"
license = "MIT"
url = "https://github.com/conan-io/conan-center-index"
description = "Fontconfig is a library for configuring and customizing font access"
homepage = "https://gitlab.freedesktop.org/fontconfig/fontconfig"
topics = ("fonts", "freedesktop")
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}

@property
def _settings_build(self):
return getattr(self, "settings_build", self.settings)

def export_sources(self):
export_conandata_patches(self)

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if self.options.shared:
del self.options.fPIC
del self.settings.compiler.libcxx
del self.settings.compiler.cppstd

def requirements(self):
self.requires("freetype/2.12.1")
self.requires("expat/2.4.9")
if self.settings.os == "Linux":
self.requires("libuuid/1.0.3")

def validate(self):
if is_msvc(self) and Version(self.version) < "2.13.93":
raise ConanInvalidConfiguration("fontconfig does not support Visual Studio for versions < 2.13.93.")

def build_requirements(self):
self.tool_requires("gperf/3.1")
self.tool_requires("pkgconf/1.9.3")
self.tool_requires("meson/0.63.3")

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True, destination=self.source_folder)

def layout(self):
basic_layout(self, src_folder="src")

def generate(self):
deps = PkgConfigDeps(self)
deps.generate()

tc = MesonToolchain(self)
tc.project_options.update({
"doc": "disabled",
"nls": "disabled",
"tests": "disabled",
"tools": "disabled"
})
tc.generate()

env = VirtualBuildEnv(self)
env.generate()

def _patch_files(self):
apply_conandata_patches(self)
replace_in_file(self, os.path.join(self.source_folder, "meson.build"),
"freetype_req = '>= 21.0.15'",
f"freetype_req = '{Version(self.deps_cpp_info['freetype'].version)}'")

def build(self):
self._patch_files()
meson = Meson(self)
meson.configure()
meson.build()

def package(self):
meson = Meson(self)
meson.install()
if is_msvc(self):
if os.path.isfile(os.path.join(self.package_folder, "lib", "libfontconfig.a")):
rename(self, os.path.join(self.package_folder, "lib", "libfontconfig.a"),
os.path.join(self.package_folder, "lib", "fontconfig.lib"))

copy(self, "COPYING", self.source_folder, os.path.join(self.package_folder, "licenses"))
rm(self, "*.pdb", os.path.join(self.package_folder, "bin"))
rm(self, "*.conf", os.path.join(self.package_folder, "bin", "etc", "fonts", "conf.d"))
rm(self, "*.def", os.path.join(self.package_folder, "lib"))
rm(self, "*.la", os.path.join(self.package_folder, "lib"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "etc"))
rmdir(self, os.path.join(self.package_folder, "share"))

def package_info(self):
self.cpp_info.set_property("cmake_find_mode", "both")
self.cpp_info.set_property("cmake_file_name", "Fontconfig")
self.cpp_info.set_property("cmake_target_name", "Fontconfig::Fontconfig")
self.cpp_info.set_property("pkg_config_name", "fontconfig")
self.cpp_info.libs = ["fontconfig"]
if self.settings.os in ("Linux", "FreeBSD"):
self.cpp_info.system_libs.extend(["m", "pthread"])

self.cpp_info.names["cmake_find_package"] = "Fontconfig"
self.cpp_info.names["cmake_find_package_multi"] = "Fontconfig"

fontconfig_file = os.path.join(self.package_folder, "bin", "etc", "fonts", "fonts.conf")
self.output.info(f"Creating FONTCONFIG_FILE environment variable: {fontconfig_file}")
self.runenv_info.prepend_path("FONTCONFIG_FILE", fontconfig_file)
self.env_info.FONTCONFIG_FILE = fontconfig_file # TODO: remove in conan v2?

fontconfig_path = os.path.join(self.package_folder, "bin", "etc", "fonts")
self.output.info(f"Creating FONTCONFIG_PATH environment variable: {fontconfig_path}")
self.runenv_info.prepend_path("FONTCONFIG_PATH", fontconfig_path)
self.env_info.FONTCONFIG_PATH = fontconfig_path # TODO: remove in conan v2?
19 changes: 19 additions & 0 deletions recipes/fontconfig/meson/patches/0001-meson-win32.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--- conf.d/link_confs.py
+++ conf.d/link_confs.py
@@ -3,6 +3,7 @@
import os
import sys
import argparse
+import platform

if __name__=='__main__':
parser = argparse.ArgumentParser()
@@ -26,7 +27,7 @@ if __name__=='__main__':
break
except OSError as e:
# Symlink privileges are not available
- if len(e.args) == 1 and 'privilege' in e.args[0]:
+ if platform.system().lower() == 'windows' and e.winerror == 1314:
break
raise
except FileExistsError:
8 changes: 8 additions & 0 deletions recipes/fontconfig/meson/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

find_package(Fontconfig CONFIG REQUIRED)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE Fontconfig::Fontconfig)
set_target_properties(${PROJECT_NAME} PROPERTIES C_STANDARD 99)
26 changes: 26 additions & 0 deletions recipes/fontconfig/meson/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
from conan.tools.build import can_run
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"

def layout(self):
cmake_layout(self)

def requirements(self):
self.requires(self.tested_reference_str)

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
24 changes: 24 additions & 0 deletions recipes/fontconfig/meson/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <fontconfig/fontconfig.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
FcConfig* config = FcInitLoadConfigAndFonts();
FcPattern* pat = FcNameParse((const FcChar8*)"Arial");
FcConfigSubstitute(config, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
char* fontFile;
FcResult result;
FcPattern* font = FcFontMatch(config, pat, &result);
if (font) {
FcChar8* file = NULL;
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
fontFile = (char*)file;
printf("%s\n",fontFile);
}
} else {
printf("Ops! I can't find any font!\n");
}
FcPatternDestroy(pat);
return EXIT_SUCCESS;
}
9 changes: 9 additions & 0 deletions recipes/fontconfig/meson/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

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

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/
${CMAKE_CURRENT_BINARY_DIR}/test_package/
)
17 changes: 17 additions & 0 deletions recipes/fontconfig/meson/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from conans import ConanFile, CMake, tools
import os


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

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)

0 comments on commit 067da2d

Please sign in to comment.