Skip to content
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

NCBI C++ Toolkit v27.0.0 #16750

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
274b1d8
Added v27.0.0, with Conan2 support
gouriano Mar 28, 2023
bcd0964
Modified per Conan center recommendations
gouriano Mar 28, 2023
223339a
Modified per Conan center recommendations
gouriano Mar 28, 2023
ba65e3a
Added verbose output into build
gouriano Mar 31, 2023
fd27356
Fixed compilation on GCC 7.2
gouriano Mar 31, 2023
eefdb78
Corrected compiler version check
gouriano Apr 3, 2023
592eeae
Fixed installation on Windows
gouriano Apr 4, 2023
8cc3d36
trigger rebuild
gouriano Apr 17, 2023
53dc735
Update recipes/ncbi-cxx-toolkit-public/all/dependencies/requirements-…
jcar87 Apr 17, 2023
99eda5a
Rely on GRPC to install PROTOBUF
gouriano Apr 17, 2023
4de55e9
Update recipes/ncbi-cxx-toolkit-public/all/test_package/CMakeLists.txt
jcar87 Apr 18, 2023
fb711b9
Update recipes/ncbi-cxx-toolkit-public/all/test_v1_package/CMakeLists…
jcar87 Apr 18, 2023
d262d42
Added patch type and description
gouriano Apr 18, 2023
ad7aacc
Change variable names to start with underscore
gouriano Apr 18, 2023
643e8fb
Added ApplicationServices framework on Mac
gouriano Apr 19, 2023
03b1276
Changed patch types
gouriano May 3, 2023
5b93304
Corrected requirements to fix conflicts.
gouriano May 4, 2023
5b424cf
Merge branch 'conan-io:master' into master
gouriano Jul 13, 2023
86eb8f3
Merge branch 'conan-io:master' into master
gouriano Sep 7, 2023
12883aa
Merge branch 'conan-io:master' into master
gouriano Sep 18, 2023
05ff3c1
Require zstd/1.5.5
gouriano Sep 18, 2023
0730040
Disable BerkeleyDB
gouriano Sep 19, 2023
ddb4291
Reenabled BerkeleyDB on Conan1
gouriano Sep 19, 2023
475bf6b
Merge branch 'conan-io:master' into master
gouriano Oct 31, 2023
6e81261
require xz_utils/5.4.4
gouriano Oct 31, 2023
b1a1b6c
Merge branch 'conan-io:master' into master
gouriano Nov 1, 2023
57f713b
Require libxml2/2.11.4
gouriano Nov 1, 2023
ccb7ba0
Removed print command.
gouriano Nov 6, 2023
d762520
Merge branch 'conan-io:master' into master
gouriano Feb 1, 2024
4237d6e
Updated conanfile and requirements
gouriano Feb 2, 2024
01c77e9
Merge branch 'conan-io:master' into master
gouriano Apr 4, 2024
7c14c2f
Merge branch 'conan-io:master' into master
gouriano Apr 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions recipes/ncbi-cxx-toolkit-public/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
sources:
"27.0.0":
url: "https://github.com/ncbi/ncbi-cxx-toolkit-public/archive/refs/tags/release-27.0.0.tar.gz"
sha256: "c8fb3f99c6fce4f170b381f3a7789c76a2ff1c23c094c9852e2e3de1fdc57277"

patches:
"27.0.0":
- patch_file: "patches/27.0.0-compiler.patch"
patch_description: "Corrected version check of GCC compiler"
patch_type: "portability"
- patch_file: "patches/27.0.0-install.patch"
patch_description: "Replaced hard-coded configuration with cmake generator expression"
patch_type: "conan"
313 changes: 313 additions & 0 deletions recipes/ncbi-cxx-toolkit-public/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
from conan import ConanFile, conan_version
from conan.errors import ConanInvalidConfiguration, ConanException
from conan.tools.microsoft import check_min_vs, is_msvc_static_runtime, is_msvc
from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, replace_in_file
from conan.tools.build import check_min_cppstd, cross_building, can_run
from conan.tools.scm import Version
from conan.tools.cmake import CMakeDeps, CMakeToolchain, CMake, cmake_layout
from conan.tools.env import VirtualRunEnv, VirtualBuildEnv
import os
import yaml
import re

required_conan_version = ">=1.53.0"


class NcbiCxxToolkit(ConanFile):
name = "ncbi-cxx-toolkit-public"
description = "NCBI C++ Toolkit -- a cross-platform application framework and a collection of libraries for working with biological data."
license = "CC0-1.0"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://ncbi.github.io/cxx-toolkit"
topics = ("ncbi", "biotechnology", "bioinformatics", "genbank", "gene",
"genome", "genetic", "sequence", "alignment", "blast",
"biological", "toolkit", "c++")
package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_targets": ["ANY"],
"with_components": ["ANY"]
}
default_options = {
"shared": False,
"fPIC": True,
"with_targets": "",
"with_components": ""
}
short_paths = True
_dependencies = None
_requirements = None
_componenttargets = set()

@property
def _min_cppstd(self):
return 17

@property
def _compilers_minimum_version(self):
return {
"gcc": "7",
"clang": "7",
"apple-clang": "10",
}

@property
def _dependencies_folder(self):
return "dependencies"

@property
def _dependencies_filename(self):
return f"dependencies-{Version(self.version).major}.{Version(self.version).minor}.yml"

@property
def _requirements_filename(self):
return f"requirements-{Version(self.version).major}.{Version(self.version).minor}.yml"

@property
def _tk_dependencies(self):
if self._dependencies is None:
dependencies_filepath = os.path.join(self.recipe_folder, self._dependencies_folder, self._dependencies_filename)
if not os.path.isfile(dependencies_filepath):
raise ConanException(f"Cannot find {dependencies_filepath}")
with open(dependencies_filepath, "r", encoding="utf-8") as f:
self._dependencies = yaml.safe_load(f)
return self._dependencies

@property
def _tk_requirements(self):
if self._requirements is None:
requirements_filepath = os.path.join(self.recipe_folder, self._dependencies_folder, self._requirements_filename)
if not os.path.isfile(requirements_filepath):
raise ConanException(f"Cannot find {requirements_filepath}")
with open(requirements_filepath, "r", encoding="utf-8") as f:
self._requirements = yaml.safe_load(f)
return self._requirements

def _translate_req(self, key):
if "Boost" in key:
key = "Boost"
if key == "BerkeleyDB" and conan_version.major > "1":
return None
if key in self._tk_requirements["disabled"].keys():
if self.settings.os in self._tk_requirements["disabled"][key]:
return None
if key in self._tk_requirements["requirements"].keys():
return self._tk_requirements["requirements"][key]
return None

def _parse_option(self, data):
_res = set()
if data != "":
_data = str(data)
_data = _data.replace(",", ";")
_data = _data.replace(" ", ";")
_res.update(_data.split(";"))
if "" in _res:
_res.remove("")
return _res

def export(self):
copy(self, self._dependencies_filename,
os.path.join(self.recipe_folder, self._dependencies_folder),
os.path.join(self.export_folder, self._dependencies_folder))
copy(self, self._requirements_filename,
os.path.join(self.recipe_folder, self._dependencies_folder),
os.path.join(self.export_folder, self._dependencies_folder))

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:
self.options.rm_safe("fPIC")

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

def requirements(self):
_alltargets = self._parse_option(self.options.with_targets)
_required_components = set()
for _t in _alltargets:
_re = re.compile(_t)
for _component in self._tk_dependencies["components"]:
_libraries = self._tk_dependencies["libraries"][_component]
for _lib in _libraries:
if _re.match(_lib) != None:
_required_components.add(_component)
break

_allcomponents = self._parse_option(self.options.with_components)
_required_components.update(_allcomponents)

if len(_required_components) > 0:
_todo = _required_components.copy()
_required_components.clear()
_next = set()
while len(_todo) > 0:
for _component in _todo:
if not _component in _required_components:
_required_components.add(_component)
if _component in self._tk_dependencies["dependencies"].keys():
for _n in self._tk_dependencies["dependencies"][_component]:
if not _n in _required_components:
_next.add(_n)
_todo = _next.copy()
_next.clear()

if len(_required_components) == 0:
_required_components.update( self._tk_dependencies["components"])
for component in _required_components:
self._componenttargets.update(self._tk_dependencies["libraries"][component])

requirements = set()
for component in _required_components:
libraries = self._tk_dependencies["libraries"][component]
for lib in libraries:
if lib in self._tk_dependencies["requirements"].keys():
requirements.update(self._tk_dependencies["requirements"][lib])

for req in requirements:
pkgs = self._translate_req(req)
if pkgs != None:
for pkg in pkgs:
self.requires(pkg)

def validate(self):
if self.settings.compiler.cppstd:
check_min_cppstd(self, self._min_cppstd)
if self.settings.os not in ["Linux", "Macos", "Windows"]:
raise ConanInvalidConfiguration("This operating system is not supported")
if is_msvc(self):
check_min_vs(self, 192)
if self.options.shared and is_msvc_static_runtime(self) and Version(self.version) < "28":
raise ConanInvalidConfiguration("This configuration is not supported")
else:
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(f"This version of {self.settings.compiler} is not supported")
if cross_building(self):
raise ConanInvalidConfiguration("Cross compilation is not supported")

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

def generate(self):
tc = CMakeToolchain(self)
tc.variables["NCBI_PTBCFG_PACKAGING"] = True
if self.options.shared:
tc.variables["NCBI_PTBCFG_ALLOW_COMPOSITE"] = True
tc.variables["NCBI_PTBCFG_PROJECT_LIST"] = "-app/netcache"
if self.options.with_targets != "":
tc.variables["NCBI_PTBCFG_PROJECT_TARGETS"] = self.options.with_targets
if len(self._componenttargets) != 0:
tc.variables["NCBI_PTBCFG_PROJECT_COMPONENTTARGETS"] = ";".join(self._componenttargets)
if is_msvc(self):
tc.variables["NCBI_PTBCFG_CONFIGURATION_TYPES"] = self.settings.build_type
tc.variables["NCBI_PTBCFG_PROJECT_TAGS"] = "-demo;-sample"
tc.generate()
CMakeDeps(self).generate()
VirtualBuildEnv(self).generate()
if can_run(self):
VirtualRunEnv(self).generate(scope="build")

def _patch_sources(self):
apply_conandata_patches(self)
if self.settings.os == "Macos":
grpc = os.path.join(self.source_folder, "src", "build-system", "cmake", "CMake.NCBIptb.grpc.cmake")
replace_in_file(self, grpc,
"COMMAND ${_cmd}",
"COMMAND ${CMAKE_COMMAND} -E env \"DYLD_LIBRARY_PATH=$ENV{DYLD_LIBRARY_PATH}\" ${_cmd}")
root = os.path.join(self.source_folder, "CMakeLists.txt")
with open(root, "w", encoding="utf-8") as f:
f.write("cmake_minimum_required(VERSION 3.15)\n")
f.write("project(ncbi-cpp)\n")
f.write("include(src/build-system/cmake/CMake.NCBItoolkit.cmake)\n")
f.write("add_subdirectory(src)\n")

def build(self):
self._patch_sources()
cmake = CMake(self)
cmake.configure()
# Visual Studio sometimes runs "out of heap space"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any links to this happening, either upstream of or on CCI so we can have a refernece to see if the problem is fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no links.
We struggled with the problem several years ago, when adopting CMake.
The workaround that finally helped was using devenv.com (instead of devenv.exe) to build the solution.
It works fine in CI. When building it in Visual Studio IDE, we still have this problem.
It is less painfull though. People do not often build the whole toolkit. Also, running the build second time, usually succeeds.
With Conan package, we saw this problem again. We do not want to try our luck. Disabling parallel build is a safe choice.

# if is_msvc(self):
# cmake.parallel = False
cmake.build()

def package(self):
cmake = CMake(self)
cmake.install()

@property
def _module_file_rel_path(self):
return os.path.join("res", "build-system", "cmake", "CMake.NCBIpkg.conan.cmake")

def package_info(self):
impfile = os.path.join(self.package_folder, "res", "ncbi-cpp-toolkit.imports")
with open(impfile, "r", encoding="utf-8") as f:
allexports = set(f.read().split()).intersection(self._componenttargets)
absent = []
for component in self._tk_dependencies["components"]:
c_libs = []
libraries = self._tk_dependencies["libraries"][component]
for lib in libraries:
if lib in allexports:
c_libs.append(lib)
if len(c_libs) == 0 and len(libraries) != 0:
absent.append(component)
for component in self._tk_dependencies["components"]:
c_libs = []
c_reqs = []
n_reqs = set()
c_deps = self._tk_dependencies["dependencies"][component]
for c in c_deps:
if c in absent:
c_deps.remove(c)
c_reqs.extend(c_deps)
libraries = self._tk_dependencies["libraries"][component]
for lib in libraries:
if lib in allexports:
c_libs.append(lib)
if lib in self._tk_dependencies["requirements"].keys():
n_reqs.update(self._tk_dependencies["requirements"][lib])
for req in n_reqs:
pkgs = self._translate_req(req)
if pkgs != None:
for pkg in pkgs:
pkg = pkg[:pkg.find("/")]
ref = pkg + "::" + pkg
c_reqs.append(ref)
if len(c_libs) != 0 or (len(libraries) == 0 and len(c_reqs) != 0):
self.cpp_info.components[component].libs = c_libs
self.cpp_info.components[component].requires = c_reqs

if self.settings.os == "Windows":
self.cpp_info.components["core"].defines.append("_UNICODE")
self.cpp_info.components["core"].defines.append("_CRT_SECURE_NO_WARNINGS=1")
else:
self.cpp_info.components["core"].defines.append("_MT")
self.cpp_info.components["core"].defines.append("_REENTRANT")
self.cpp_info.components["core"].defines.append("_THREAD_SAFE")
self.cpp_info.components["core"].defines.append("_FILE_OFFSET_BITS=64")
if self.options.shared:
self.cpp_info.components["core"].defines.append("NCBI_DLL_BUILD")
if self.settings.build_type == "Debug":
self.cpp_info.components["core"].defines.append("_DEBUG")
else:
self.cpp_info.components["core"].defines.append("NDEBUG")
if self.settings.os == "Windows":
self.cpp_info.components["core"].system_libs = ["ws2_32", "dbghelp"]
elif self.settings.os == "Linux":
self.cpp_info.components["core"].system_libs = ["dl", "rt", "m", "pthread", "resolv"]
elif self.settings.os == "Macos":
self.cpp_info.components["core"].system_libs = ["dl", "c", "m", "pthread", "resolv"]
self.cpp_info.components["core"].frameworks = ["ApplicationServices"]
self.cpp_info.components["core"].builddirs.append("res")
build_modules = [self._module_file_rel_path]
self.cpp_info.components["core"].build_modules = build_modules
self.cpp_info.set_property("cmake_build_modules", build_modules)
Loading
Loading