Skip to content

Commit

Permalink
(#18797) flatcc: migrate to Conan v2
Browse files Browse the repository at this point in the history
* flatcc: migrate to Conan v2

* flatcc: make test_package test() more robust

* flatcc: fix test_package

* flatcc: fix shared library access during test build

* flatcc: fix_apple_shared_install_name()

* flatcc: correct required_conan_version

* flatcc: don't print PATH

* flatcc: disable cross-building if flatcc_cli cannot be run during the build

* flatcc: add macOS workaround

* flatcc: skip macOS shared test on Conan v1
  • Loading branch information
valgur authored Jan 15, 2024
1 parent 90fe0a6 commit fcd28b1
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 124 deletions.
7 changes: 0 additions & 7 deletions recipes/flatcc/all/CMakeLists.txt

This file was deleted.

149 changes: 77 additions & 72 deletions recipes/flatcc/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,111 +1,116 @@
from conans import CMake, ConanFile, tools
from conans.errors import ConanInvalidConfiguration
import os
import functools

required_conan_version = ">=1.33.0"
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.apple import fix_apple_shared_install_name
from conan.tools.build import cross_building, can_run
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan.tools.files import copy, get
from conan.tools.microsoft import is_msvc
from conan.tools.scm import Version

required_conan_version = ">=1.53.0"


class FlatccConan(ConanFile):
name = "flatcc"
description = "C language binding for Flatbuffers, an efficient cross platform serialization library"
license = "Apache-2.0"
topics = ("flatbuffers", "serialization")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/dvidelabs/flatcc"
topics = ("flatbuffers", "serialization")

package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = { "shared": [True, False],
"fPIC": [True, False],
"portable": [True, False],
"gnu_posix_memalign": [True, False],
"runtime_lib_only": [True, False],
"verify_assert": [True, False],
"verify_trace": [True, False],
"reflection": [True, False],
"native_optim": [True, False],
"fast_double": [True, False],
"ignore_const_condition": [True, False],
options = {
"shared": [True, False],
"fPIC": [True, False],
"portable": [True, False],
"gnu_posix_memalign": [True, False],
"runtime_lib_only": [True, False],
"verify_assert": [True, False],
"verify_trace": [True, False],
"reflection": [True, False],
"native_optim": [True, False],
"fast_double": [True, False],
"ignore_const_condition": [True, False],
}
default_options = { "shared": False,
"fPIC": True,
"portable": False,
"gnu_posix_memalign": True,
"runtime_lib_only": False,
"verify_assert": False,
"verify_trace": False,
"reflection": True,
"native_optim": False,
"fast_double": False,
"ignore_const_condition": False
default_options = {
"shared": False,
"fPIC": True,
"portable": False,
"gnu_posix_memalign": True,
"runtime_lib_only": False,
"verify_assert": False,
"verify_trace": False,
"reflection": True,
"native_optim": False,
"fast_double": False,
"ignore_const_condition": False,
}
generators = "cmake"
exports_sources = ["CMakeLists.txt"]

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

@property
def _build_subfolder(self):
return "build_subfolder"

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

def configure(self):
if self.options.shared:
del self.options.fPIC
self.options.rm_safe("fPIC")

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

def validate(self):
if self.settings.os == "Windows":
if self.settings.compiler == "Visual Studio" and self.options.shared:
#Building flatcc shared libs with Visual Studio is broken
if is_msvc(self) and self.options.shared:
# Building flatcc shared libs with Visual Studio is broken
raise ConanInvalidConfiguration("Building flatcc libraries shared is not supported")
if tools.Version(self.version) == "0.6.0" and self.settings.compiler == "gcc":
if Version(self.version) == "0.6.0" and self.settings.compiler == "gcc":
raise ConanInvalidConfiguration("Building flatcc with MinGW is not supported")
if cross_building(self) and not can_run(self):
raise ConanInvalidConfiguration(f"Cross-building for a non-native architecture ({self.settings.arch}) is not supported")

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

@functools.lru_cache(1)
def _configure_cmake(self):
cmake = CMake(self)
cmake.definitions["FLATCC_PORTABLE"] = self.options.portable
cmake.definitions["FLATCC_GNU_POSIX_MEMALIGN"] = self.options.gnu_posix_memalign
cmake.definitions["FLATCC_RTONLY"] = self.options.runtime_lib_only
cmake.definitions["FLATCC_INSTALL"] = True
cmake.definitions["FLATCC_COVERAGE"] = False
cmake.definitions["FLATCC_DEBUG_VERIFY"] = self.options.verify_assert
cmake.definitions["FLATCC_TRACE_VERIFY"] = self.options.verify_trace
cmake.definitions["FLATCC_REFLECTION"] = self.options.reflection
cmake.definitions["FLATCC_NATIVE_OPTIM"] = self.options.native_optim
cmake.definitions["FLATCC_FAST_DOUBLE"] = self.options.fast_double
cmake.definitions["FLATCC_IGNORE_CONST_COND"] = self.options.ignore_const_condition
cmake.definitions["FLATCC_TEST"] = False
cmake.definitions["FLATCC_ALLOW_WERROR"] = False
cmake.configure(build_folder=self._build_subfolder)
return cmake
def generate(self):
tc = CMakeToolchain(self)
tc.variables["FLATCC_PORTABLE"] = self.options.portable
tc.variables["FLATCC_GNU_POSIX_MEMALIGN"] = self.options.gnu_posix_memalign
tc.variables["FLATCC_RTONLY"] = self.options.runtime_lib_only
tc.variables["FLATCC_INSTALL"] = True
tc.variables["FLATCC_COVERAGE"] = False
tc.variables["FLATCC_DEBUG_VERIFY"] = self.options.verify_assert
tc.variables["FLATCC_TRACE_VERIFY"] = self.options.verify_trace
tc.variables["FLATCC_REFLECTION"] = self.options.reflection
tc.variables["FLATCC_NATIVE_OPTIM"] = self.options.native_optim
tc.variables["FLATCC_FAST_DOUBLE"] = self.options.fast_double
tc.variables["FLATCC_IGNORE_CONST_COND"] = self.options.ignore_const_condition
tc.variables["FLATCC_TEST"] = False
tc.variables["FLATCC_ALLOW_WERROR"] = False
tc.generate()

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

def package(self):
cmake = self._configure_cmake()
cmake = CMake(self)
cmake.install()
if self.settings.build_type == "Debug" and not tools.os_info.is_windows:
if self.settings.build_type == "Debug" and not self.settings.os == "Windows":
debug_suffix = "_d" if self.settings.build_type == "Debug" else ""
os.rename(os.path.join(self.package_folder, "bin", "flatcc%s" % debug_suffix),
os.rename(os.path.join(self.package_folder, "bin", f"flatcc{debug_suffix}"),
os.path.join(self.package_folder, "bin", "flatcc"))
# Copy license file
self.copy("LICENSE", dst="licenses", src=self._source_subfolder)
copy(self, "LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
fix_apple_shared_install_name(self)

def package_info(self):
bin_path = os.path.join(self.package_folder, "bin")
self.output.info('Appending PATH environment variable: %s' % bin_path)
self.env_info.PATH.append(bin_path)
debug_suffix = "_d" if self.settings.build_type == "Debug" else ""
if not self.options.runtime_lib_only:
self.cpp_info.libs.append("flatcc%s" % debug_suffix)
self.cpp_info.libs.append("flatccrt%s" % debug_suffix)
self.cpp_info.libs.append(f"flatcc{debug_suffix}")
self.cpp_info.libs.append(f"flatccrt{debug_suffix}")

# TODO: to remove in conan v2
bin_path = os.path.join(self.package_folder, "bin")
self.env_info.PATH.append(bin_path)
29 changes: 10 additions & 19 deletions recipes/flatcc/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.1)
project(flatcc_example)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
cmake_minimum_required(VERSION 3.15)
project(flatcc_example LANGUAGES C)

find_package(flatcc REQUIRED CONFIG)

Expand All @@ -14,20 +11,14 @@ include_directories("${GEN_DIR}" "${INC_DIR}")

add_executable(monster monster.c)

#On MacOS System Integrity Protection (SIP) will clear the DYLD_LIBRARY_PATH variable.
#As a result calling flatcc from cmake will currently not work if the flatcc executable
# is linked shared. As a workaround we generate the flatbuffer C files in the Conan recipe
# when on MacOS and flatcc option 'shared' is True.
if (NOT MACOS_SIP_WORKAROUND)
add_custom_target(gen_monster_fbs ALL)
add_custom_command (
TARGET gen_monster_fbs
COMMAND cmake -E make_directory "${GEN_DIR}"
COMMAND flatcc -a -o "${GEN_DIR}" "${FBS_DIR}/monster.fbs"
DEPENDS flatcc "${FBS_DIR}/monster.fbs"
)
add_custom_target(gen_monster_fbs ALL)
add_custom_command (
TARGET gen_monster_fbs
COMMAND cmake -E make_directory "${GEN_DIR}"
COMMAND flatcc -a -o "${GEN_DIR}" "${FBS_DIR}/monster.fbs"
DEPENDS flatcc "${FBS_DIR}/monster.fbs"
)

add_dependencies(monster gen_monster_fbs)
endif()
add_dependencies(monster gen_monster_fbs)

target_link_libraries(monster flatcc::flatcc)
63 changes: 37 additions & 26 deletions recipes/flatcc/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
import os.path
import os

from conans import ConanFile, CMake, tools, RunEnvironment
from conans.errors import ConanException
from conan import ConanFile, conan_version
from conan.tools.apple import is_apple_os
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
from conan.tools.env import VirtualRunEnv


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

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

def build_requirements(self):
self.tool_requires(self.tested_reference_str)

def layout(self):
cmake_layout(self)

@property
def _skip_shared_macos(self):
return conan_version.major == 1 and self.options["flatcc"].shared and is_apple_os(self)

def generate(self):
VirtualRunEnv(self).generate(scope="build")
VirtualRunEnv(self).generate(scope="run")


def build(self):
if tools.cross_building(self):
if self._skip_shared_macos:
return

env_build = RunEnvironment(self)
with tools.environment_append(env_build.vars):
cmake = CMake(self)
if tools.os_info.is_macos and self.options["flatcc"].shared:
# Because of MacOS System Integraty Protection it is currently not possible to run the flatcc
# executable from cmake if it is linked shared. As a temporary work-around run flatcc here in
# the build function.
tools.mkdir(os.path.join(self.build_folder, "generated"))
self.run("flatcc -a -o " + os.path.join(self.build_folder, "generated") + " " + os.path.join(self.source_folder, "monster.fbs"), run_environment=True)
cmake.definitions["MACOS_SIP_WORKAROUND"] = True
cmake.configure()
cmake.build()
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if tools.cross_building(self):
bin_path = os.path.join(self.deps_cpp_info["flatcc"].rootpath, "bin", "flatcc")
if not os.path.isfile(bin_path) or not os.access(bin_path, os.X_OK):
raise ConanException("flatcc doesn't exist.")
else:
bin_path = os.path.join(self.build_folder, "bin", "monster")
self.run(bin_path, cwd=self.source_folder, run_environment=True)
if self._skip_shared_macos:
return
if can_run(self):
self.run("flatcc --version")
bin_path = os.path.join(self.cpp.build.bindir, "monster")
self.run(bin_path, env="conanrun")
8 changes: 8 additions & 0 deletions recipes/flatcc/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.15)
project(test_package)

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

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/
${CMAKE_CURRENT_BINARY_DIR}/test_package/)
40 changes: 40 additions & 0 deletions recipes/flatcc/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os.path

from conans import ConanFile, CMake, tools, RunEnvironment
from conans.errors import ConanException


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

@property
def _skip_shared_macos(self):
# Because of MacOS System Integraty Protection it is currently not possible to run the flatcc
# executable from cmake if it is linked shared. As a temporary work-around run flatcc here in
# the build function.
return self.options["flatcc"].shared and tools.os_info.is_macos

def build(self):
if tools.cross_building(self):
return

if self._skip_shared_macos:
return

env_build = RunEnvironment(self)
with tools.environment_append(env_build.vars):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if self._skip_shared_macos:
return
if tools.cross_building(self):
bin_path = os.path.join(self.deps_cpp_info["flatcc"].rootpath, "bin", "flatcc")
if not os.path.isfile(bin_path) or not os.access(bin_path, os.X_OK):
raise ConanException("flatcc doesn't exist.")
else:
bin_path = os.path.join(self.build_folder, "bin", "monster")
self.run(bin_path, cwd=self.source_folder, run_environment=True)

0 comments on commit fcd28b1

Please sign in to comment.