diff --git a/recipes/yojimbo/all/conanfile.py b/recipes/yojimbo/all/conanfile.py
index 96de2407727bd..a727c0b4af7a6 100644
--- a/recipes/yojimbo/all/conanfile.py
+++ b/recipes/yojimbo/all/conanfile.py
@@ -1,117 +1,173 @@
import os
-from conans import ConanFile, MSBuild, AutoToolsBuildEnvironment, tools
-from conans.errors import ConanInvalidConfiguration
+import textwrap
+from pathlib import Path
+
import yaml
+from conan import ConanFile
+from conan.errors import ConanInvalidConfiguration
+from conan.tools.env import VirtualBuildEnv
+from conan.tools.files import chdir, collect_libs, copy, get, replace_in_file, rmdir, save
+from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain
+from conan.tools.layout import basic_layout
+from conan.tools.microsoft import MSBuild, MSBuildDeps, MSBuildToolchain, is_msvc
+from conan.tools.scm import Version
+
+required_conan_version = ">=2.0.0"
class YojimboConan(ConanFile):
name = "yojimbo"
- url = "https://github.com/conan-io/conan-center-index"
- homepage = "https://github.com/networkprotocol/yojimbo"
- topics = ("conan", "yojimbo", "game", "udp", "protocol", "client-server", "multiplayer-game-server")
description = "A network library for client/server games written in C++"
license = "BSD-3-Clause"
- exports = "submoduledata.yml"
- build_requires = "premake/5.0.0-alpha15"
- settings = "os", "arch", "compiler", "build_type"
- options = {"fPIC": [True, False]}
- default_options = {"fPIC": True}
+ url = "https://github.com/conan-io/conan-center-index"
+ homepage = "https://github.com/networkprotocol/yojimbo"
+ topics = ("game", "udp", "protocol", "client-server", "multiplayer-game-server")
- _source_subfolder = "source_subfolder"
- _build_subfolder = "build_subfolder"
+ package_type = "static-library"
+ settings = "os", "arch", "compiler", "build_type"
+ options = {
+ "fPIC": [True, False],
+ }
+ default_options = {
+ "fPIC": True,
+ }
- def configure(self):
- if self.settings.arch != "x86_64":
- raise ConanInvalidConfiguration("Only 64-bit architecture supported")
+ def export_sources(self):
+ copy(self, "submoduledata.yml", src=self.recipe_folder, dst=self.export_sources_folder)
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
- def requirements(self):
- self.requires("libsodium/1.0.18")
- self.requires("mbedtls/2.25.0")
-
- def source(self):
- tools.get(**self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder)
-
- submodule_filename = os.path.join(self.recipe_folder, 'submoduledata.yml')
- with open(submodule_filename, 'r') as submodule_stream:
- submodules_data = yaml.load(submodule_stream)
- for path, submodule in submodules_data["submodules"][self.version].items():
- submodule_data = {
- "url": submodule["url"],
- "sha256": submodule["sha256"],
- "destination": os.path.join(self._source_subfolder, submodule["destination"]),
- "strip_root": True
- }
-
- tools.get(**submodule_data)
- submodule_source = os.path.join(self._source_subfolder, path)
- tools.rmdir(submodule_source)
-
- def build(self):
+ def layout(self):
+ basic_layout(self, src_folder="src")
- # Before building we need to make some edits to the premake file to build using conan dependencies rather than local/bundled
+ def requirements(self):
+ self.requires("libsodium/1.0.19")
+ self.requires("mbedtls/2.28.4") # v3+ is not supported
- # Generate the list of dependency include and library paths as strings
- include_path_str = ', '.join('"{0}"'.format(p) for p in self.deps_cpp_info["libsodium"].include_paths + self.deps_cpp_info["mbedtls"].include_paths)
- lib_path_str = ', '.join('"{0}"'.format(p) for p in self.deps_cpp_info["libsodium"].lib_paths + self.deps_cpp_info["mbedtls"].lib_paths)
+ def validate_build(self):
+ if self.settings_build.build_type == "Debug":
+ if self.settings_build.os != "Windows" and self.settings_build.compiler == "gcc" and Version(self.settings_build.compiler.version) < 8:
+ raise ConanInvalidConfiguration("Debug build requires GCC >= 8 due to util-linux-libuuid")
- premake_path = os.path.join(self._source_subfolder, "premake5.lua")
+ def build_requirements(self):
+ self.tool_requires("premake/5.0.0-alpha15")
- if self.settings.os == "Windows":
-
- # Replace Windows directory seperator
- include_path_str = include_path_str.replace("\\", "/")
- lib_path_str = lib_path_str.replace("\\", "/")
-
- # Edit the premake script to use conan rather than bundled dependencies
- tools.replace_in_file(premake_path, "includedirs { \".\", \"./windows\"", "includedirs { \".\", %s" % include_path_str, strict=True)
- tools.replace_in_file(premake_path, "libdirs { \"./windows\" }", "libdirs { %s }" % lib_path_str, strict=True)
-
- # Edit the premake script to change the name of libsodium
- tools.replace_in_file(premake_path, "\"sodium\"", "\"libsodium\"", strict=True)
-
+ def source(self):
+ get(self, **self.conan_data["sources"][self.version], strip_root=True)
+
+ submodule_filename = os.path.join(self.export_sources_folder, "submoduledata.yml")
+ with open(submodule_filename, "r", encoding="utf8") as submodule_stream:
+ submodules_data = yaml.load(submodule_stream, Loader=yaml.SafeLoader)
+ for path, submodule_data in submodules_data["submodules"][self.version].items():
+ get(self, **submodule_data, strip_root=True)
+ submodule_source = os.path.join(self.source_folder, path)
+ rmdir(self, submodule_source)
+
+ @property
+ def _conan_paths_lua(self):
+ return os.path.join(self.generators_folder, "conan_paths.lua")
+
+ def generate(self):
+ venv = VirtualBuildEnv(self)
+ venv.generate()
+ if is_msvc(self):
+ tc = MSBuildToolchain(self)
+ tc.generate()
+ tc = MSBuildDeps(self)
+ tc.generate()
else:
-
- # Edit the premake script to use conan rather than local dependencies
- tools.replace_in_file(premake_path, "\"/usr/local/include\"", include_path_str, strict=True)
-
-
- # Build using premake
-
- if self.settings.compiler == "Visual Studio":
- generator = "vs" + {"16": "2019",
- "15": "2017",
- "14": "2015",
- "12": "2013",
- "11": "2012",
- "10": "2010",
- "9": "2008",
- "8": "2005"}.get(str(self.settings.compiler.version))
+ tc = AutotoolsToolchain(self)
+ tc.generate()
+ tc = AutotoolsDeps(self)
+ tc.generate()
+
+ deps = list(reversed(self.dependencies.host.topological_sort.values()))
+ includedirs = ', '.join(f'"{p}"'.replace("\\", "/") for dep in deps for p in dep.cpp_info.aggregated_components().includedirs)
+ libdirs = ', '.join(f'"{p}"'.replace("\\", "/") for dep in deps for p in dep.cpp_info.aggregated_components().libdirs)
+ save(self, self._conan_paths_lua,
+ "conan_includedirs = {" + includedirs + "}\n"
+ "conan_libdirs = {" + libdirs + "}\n")
+
+ def _patch_sources(self):
+ premake_path = os.path.join(self.source_folder, "premake5.lua")
+ replace_in_file(self, premake_path, ', "/usr/local/include"', "")
+ if self.settings.os == "Windows":
+ replace_in_file(self, premake_path, '"sodium"', '"libsodium"')
+
+ # Inject Conan dependencies
+ conan_paths_lua = self._conan_paths_lua.replace("\\", "/")
+ save(self, premake_path,
+ f"\ndofile('{conan_paths_lua}')\n" +
+ textwrap.dedent("""
+ workspace "Yojimbo"
+ configurations { "Debug", "Release" }
+ includedirs { conan_includedirs }
+ libdirs { conan_libdirs }
+ """), append=True)
+
+ @property
+ def _premake_generator(self):
+ if is_msvc(self):
+ generator = "vs2015"
else:
generator = "gmake2"
+ return generator
+
+ def _inject_msbuild_toolchain(self):
+ vcxproj_files = list(self.source_path.rglob("*.vcxproj"))
+ platform_toolset = MSBuildToolchain(self).toolset
+ import_conan_generators = ""
+ for props_file in ["conantoolchain.props", "conandeps.props"]:
+ props_path = os.path.join(self.generators_folder, props_file)
+ if os.path.exists(props_path):
+ import_conan_generators += f""
+ for vcxproj_file in vcxproj_files:
+ replace_in_file(self, vcxproj_file, "v140", platform_toolset)
+ if props_path:
+ replace_in_file(
+ self, vcxproj_file,
+ r'',
+ rf'{import_conan_generators}',
+ )
- with tools.chdir(self._source_subfolder):
- self.run("premake5 %s" % generator)
-
- if self.settings.compiler == "Visual Studio":
+ def build(self):
+ self._patch_sources()
+ # Build using premake
+ with chdir(self, self.source_folder):
+ self.run(f"premake5 {self._premake_generator}")
+ if is_msvc(self):
+ self._inject_msbuild_toolchain()
msbuild = MSBuild(self)
msbuild.build("Yojimbo.sln")
else:
+ # Remove incorrect arch flags
+ for make_file in Path(self.source_folder).rglob("*.make"):
+ if self.settings.arch not in ["x86", "x86_64"]:
+ replace_in_file(self, make_file, "-msse2", "", strict=False)
+ if self.settings.arch != "x86_64":
+ replace_in_file(self, make_file, "-m64", "", strict=False)
config = "debug" if self.settings.build_type == "Debug" else "release"
config += "_x64"
- env_build = AutoToolsBuildEnvironment(self)
- env_build.make(args=["config=%s" % config])
-
+ autotools = Autotools(self)
+ autotools.make(args=[f"config={config}"])
def package(self):
- self.copy(pattern="LICENCE", dst="licenses", src=self._source_subfolder)
- self.copy(pattern="yojimbo.h", dst="include", src=self._source_subfolder)
-
- self.copy(pattern="*/yojimbo.lib", dst="lib", keep_path=False)
- self.copy(pattern="*/libyojimbo.a", dst="lib", keep_path=False)
+ copy(self, "LICENCE",
+ dst=os.path.join(self.package_folder, "licenses"),
+ src=self.source_folder)
+ copy(self, "yojimbo.h",
+ dst=os.path.join(self.package_folder, "include"),
+ src=self.source_folder)
+ copy(self, "*/yojimbo.lib",
+ dst=os.path.join(self.package_folder, "lib"),
+ src=self.source_folder,
+ keep_path=False)
+ copy(self, "*/libyojimbo.a",
+ dst=os.path.join(self.package_folder, "lib"),
+ src=self.source_folder,
+ keep_path=False)
def package_info(self):
- self.cpp_info.libs = tools.collect_libs(self)
+ self.cpp_info.libs = collect_libs(self)
diff --git a/recipes/yojimbo/all/test_package/CMakeLists.txt b/recipes/yojimbo/all/test_package/CMakeLists.txt
index 04e93484921eb..51b30ace87e86 100644
--- a/recipes/yojimbo/all/test_package/CMakeLists.txt
+++ b/recipes/yojimbo/all/test_package/CMakeLists.txt
@@ -1,8 +1,7 @@
-cmake_minimum_required(VERSION 3.1.0)
-project(test_package)
+cmake_minimum_required(VERSION 3.15)
+project(test_package LANGUAGES CXX)
-include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
-conan_basic_setup()
+find_package(yojimbo REQUIRED CONFIG)
add_executable(${PROJECT_NAME} test_package.cpp)
-target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
+target_link_libraries(${PROJECT_NAME} PRIVATE yojimbo::yojimbo)
diff --git a/recipes/yojimbo/all/test_package/conanfile.py b/recipes/yojimbo/all/test_package/conanfile.py
index bd7165a553cf4..ef5d7042163ec 100644
--- a/recipes/yojimbo/all/test_package/conanfile.py
+++ b/recipes/yojimbo/all/test_package/conanfile.py
@@ -1,10 +1,19 @@
-from conans import ConanFile, CMake, tools
+from conan import ConanFile
+from conan.tools.build import can_run
+from conan.tools.cmake import cmake_layout, CMake
import os
class TestPackageConan(ConanFile):
- settings = "os", "compiler", "build_type", "arch"
- generators = "cmake"
+ settings = "os", "arch", "compiler", "build_type"
+ generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
+ test_type = "explicit"
+
+ def requirements(self):
+ self.requires(self.tested_reference_str)
+
+ def layout(self):
+ cmake_layout(self)
def build(self):
cmake = CMake(self)
@@ -12,6 +21,6 @@ def build(self):
cmake.build()
def test(self):
- if not tools.cross_building(self.settings):
- bin_path = os.path.join("bin", "test_package")
- self.run(bin_path, run_environment=True)
+ if can_run(self):
+ bin_path = os.path.join(self.cpp.build.bindir, "test_package")
+ self.run(bin_path, env="conanrun")
diff --git a/recipes/yojimbo/all/test_package/test_package.cpp b/recipes/yojimbo/all/test_package/test_package.cpp
index c2571a92dbdc9..634213bbf1d4a 100644
--- a/recipes/yojimbo/all/test_package/test_package.cpp
+++ b/recipes/yojimbo/all/test_package/test_package.cpp
@@ -10,10 +10,10 @@ int main()
std::cout << "Failed to initialize Yojimbo!\n";
return 1;
}
-
+
std::cout << "Succesfully initialized Yojimbo\n";
-
+
ShutdownYojimbo();
-
+
return 0;
}