-
Notifications
You must be signed in to change notification settings - Fork 10
/
conanfile.py
323 lines (302 loc) · 16.3 KB
/
conanfile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
import shutil
import json
import os
import re
import subprocess
from conan.tools.files import rm
from conan.tools.scm import Git
from conan.tools.apple import is_apple_os
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan import ConanFile
required_conan_version = '>=2.7'
def semver_parse(s):
m = re.match('^v?(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(\\.(?P<tweak>0|[1-9]\d*))?(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$', s)
return m.groupdict() if m else None
def semver_string(semver):
s = str(semver['major']) + '.' + \
str(semver['minor']) + '.' + str(semver['patch'])
if not semver['tweak'] is None and semver['tweak'] != 0:
s += '.' + str(semver['tweak'])
if not semver['prerelease'] is None and semver['prerelease'] != '':
s += '-' + semver['prerelease']
return s
def semver_string_with_buildmetadata(semver):
s = semver_string(semver)
if not semver['buildmetadata'] is None and semver['buildmetadata'] != '':
s += '+' + semver['buildmetadata']
return s
class libmdbx(ConanFile):
name = 'mdbx'
package_type = 'library'
description = 'One of the fastest embeddable key-value ACID database without WAL. libmdbx surpasses the legendary LMDB in terms of reliability, features and performance.'
license = 'Apache-2.0'
author = 'Leo Yuriev <[email protected]>'
homepage = 'https://libmdbx.dqdkfa.ru'
url = 'https://gitflic.ru/project/erthink/libmdbx.git'
topics = ('embedded-database', 'key-value', 'btree', 'LMDB', 'storage-engine',
'data-storage', 'nosql', 'ACID', 'MVCC', 'MDBX')
no_copy_source = True
test_type = 'explicit'
build_policy = 'missing'
revision_mode = 'scm'
languages = 'C', 'C++'
provides = 'libmdbx'
implements = ['auto_shared_fpic']
# upload_policy = 'skip'
# exports_sources = 'LICENSE', 'NOTICE', 'CMakeLists.txt', '*.h', '*.h++', '*.c', '*.c++', 'ntdll.def', 'man1/*', 'cmake/*', 'config.h.in'
settings = 'os', 'compiler', 'build_type', 'arch'
options = {
'mdbx.64bit_atomic': ['Auto', True, False],
'mdbx.64bit_cas': ['Auto', True, False],
'mdbx.apple.speed_insteadof_durability': ['Default', True, False],
'mdbx.avoid_msync': ['Auto', True, False],
'mdbx.build_cxx': ['Default', True, False],
'mdbx.build_tools': ['Default', True, False],
'mdbx.cacheline_size': ['Auto', 16, 32, 64, 128, 256],
'mdbx.disable_validation': ['Default', True, False],
'mdbx.enable_bigfoot': ['Default', True, False],
'mdbx.enable_dbi_lockfree': ['Default', True, False],
'mdbx.enable_dbi_sparse': ['Default', True, False],
'mdbx.enable_pgop_stat': ['Default', True, False],
'mdbx.enable_profgc': ['Default', True, False],
'mdbx.enable_refund': ['Default', True, False],
'mdbx.env_checkpid': ['Default', True, False],
'mdbx.force_assertions': ['Default', True, False],
'mdbx.have_builtin_cpu_supports': ['Auto', True, False],
'mdbx.locking': ['Auto', 'WindowsFileLocking', 'SystemV', 'POSIX1988', 'POSIX2001', 'POSIX2008'],
'mdbx.mmap_incoherent_file_write': ['Auto', True, False],
'mdbx.mmap_needs_jolt': ['Auto', True, False],
'mdbx.trust_rtc': ['Default', True, False],
'mdbx.txn_checkowner': ['Default', True, False],
'mdbx.unaligned_ok': ['Auto', True, False],
'mdbx.use_copyfilerange': ['Auto', True, False],
'mdbx.use_mincore': ['Auto', True, False],
'mdbx.use_ofdlocks': ['Auto', True, False],
'mdbx.use_sendfile': ['Auto', True, False],
'mdbx.without_msvc_crt': ['Default', True, False],
'shared': [True, False],
}
default_options = {
'mdbx.64bit_atomic': 'Auto',
'mdbx.64bit_cas': 'Auto',
'mdbx.apple.speed_insteadof_durability': 'Default',
'mdbx.avoid_msync': 'Auto',
'mdbx.build_cxx': 'Default',
'mdbx.build_tools': 'Default',
'mdbx.cacheline_size': 'Auto',
'mdbx.disable_validation': 'Default',
'mdbx.enable_bigfoot': 'Default',
'mdbx.enable_dbi_lockfree': 'Default',
'mdbx.enable_dbi_sparse': 'Default',
'mdbx.enable_pgop_stat': 'Default',
'mdbx.enable_profgc': 'Default',
'mdbx.enable_refund': 'Default',
'mdbx.env_checkpid': 'Default',
'mdbx.force_assertions': 'Default',
'mdbx.have_builtin_cpu_supports': 'Auto',
'mdbx.locking': 'Auto',
'mdbx.mmap_incoherent_file_write': 'Auto',
'mdbx.mmap_needs_jolt': 'Auto',
'mdbx.trust_rtc': 'Default',
'mdbx.txn_checkowner': 'Default',
'mdbx.unaligned_ok': 'Auto',
'mdbx.use_copyfilerange': 'Auto',
'mdbx.use_mincore': 'Auto',
'mdbx.use_ofdlocks': 'Auto',
'mdbx.use_sendfile': 'Auto',
'mdbx.without_msvc_crt': 'Default',
'shared': True,
}
options_description = {
'mdbx.64bit_atomic': 'Advanced: Assume 64-bit operations are atomic and not splitted to 32-bit halves. ',
'mdbx.64bit_cas': 'Advanced: Assume 64-bit atomic compare-and-swap operation is available. ',
'mdbx.apple.speed_insteadof_durability': 'Disable using `fcntl(F_FULLFSYNC)` for a performance reasons at the cost of durability on power failure. ',
'mdbx.avoid_msync': 'Disable in-memory database updating with consequent flush-to-disk/msync syscall in `MDBX_WRITEMAP` mode. ',
'mdbx.build_cxx': 'Build C++ portion. ',
'mdbx.build_tools': 'Build CLI tools (mdbx_chk/stat/dump/load/copy/drop). ',
'mdbx.cacheline_size': 'Advanced: CPU cache line size for data alignment to avoid cache line false-sharing. ',
'mdbx.disable_validation': 'Disable some checks to reduce an overhead and detection probability of database corruption to a values closer to the LMDB. ',
'mdbx.enable_bigfoot': 'Chunking long list of retired pages during huge transactions commit to avoid use sequences of pages. ',
'mdbx.enable_dbi_lockfree': 'Support for deferred releasing and a lockfree path to quickly open DBI handles. ',
'mdbx.enable_dbi_sparse': 'Support for sparse sets of DBI handles to reduce overhead when starting and processing transactions. ',
'mdbx.enable_pgop_stat': 'Gathering statistics for page operations. ',
'mdbx.enable_profgc': 'Profiling of GC search and updates. ',
'mdbx.enable_refund': 'Online database zero-cost auto-compactification during write-transactions. ',
'mdbx.env_checkpid': "Checking PID inside libmdbx's API against reuse database environment after the `fork()`. ",
'mdbx.force_assertions': 'Forces assertion checking even for release builds. ',
'mdbx.have_builtin_cpu_supports': 'Advanced: Assume the compiler and target system has `__builtin_cpu_supports()`. ',
'mdbx.locking': 'Advanced: Choices the locking implementation. ',
'mdbx.mmap_incoherent_file_write': "Advanced: Assume system don't have unified page cache and/or file write operations incoherent with memory-mapped files. ",
'mdbx.mmap_needs_jolt': 'Advanced: Assume system needs explicit syscall to sync/flush/write modified mapped memory. ',
'mdbx.trust_rtc': 'Advanced: Does a system have battery-backed Real-Time Clock or just a fake. ',
'mdbx.txn_checkowner': 'Checking transaction owner thread against misuse transactions from other threads. ',
'mdbx.unaligned_ok': 'Advanced: Assume a target CPU and/or the compiler support unaligned access. ',
'mdbx.use_copyfilerange': 'Advanced: Use `copy_file_range()` syscall. ',
'mdbx.use_mincore': "Use Unix' `mincore()` to determine whether database pages are resident in memory. ",
'mdbx.use_ofdlocks': 'Advanced: Use POSIX OFD-locks. ',
'mdbx.use_sendfile': 'Advancedc: Use `sendfile()` syscall. ',
'mdbx.without_msvc_crt': 'Avoid dependence from MSVC CRT and use ntdll.dll instead. ',
}
build_metadata = None
def config_options(self):
if self.settings.get_safe('os') != 'Linux':
self.options.rm_safe('mdbx.use_copyfilerange')
self.options.rm_safe('mdbx.use_sendfile')
if self.settings.get_safe('os') == 'Windows':
self.default_options['mdbx.avoid_msync'] = True
self.options.rm_safe('mdbx.env_checkpid')
self.options.rm_safe('mdbx.locking')
self.options.rm_safe('mdbx.mmap_incoherent_file_write')
self.options.rm_safe('mdbx.use_mincore')
self.options.rm_safe('mdbx.use_ofdlocks')
else:
self.options.rm_safe('mdbx.without_msvc_crt')
if is_apple_os(self):
self.options.rm_safe('mdbx.mmap_incoherent_file_write')
else:
self.options.rm_safe('mdbx.apple.speed_insteadof_durability')
def fetch_versioninfo_from_git(self):
git = Git(self, folder=self.recipe_folder)
git_timestamp = git.run('show --no-patch --format=%cI HEAD')
git_tree = git.run('show --no-patch --format=%T HEAD')
git_commit = git.run('show --no-patch --format=%H HEAD')
if git.run('rev-list --tags --count') == 0:
git.run('fetch --tags')
git_last_vtag = git.run('describe --tags --abbrev=0 --match=v[0-9]*')
if git_last_vtag == '':
git_describe = git.run('describe --all --long --always')
git_semver = semver_parse(
'0.0.0.' + git.run('rev-list --count --remove-empty --no-merges HEAD'))
else:
git_describe = git.run('describe --tags --long --match=v[0-9]*')
git_version = '.'.join(
map(str, re.split('[-v.]+', git.run('describe --tags --match=v[0-9]*'))[1:5]))
git_semver = semver_parse(git_last_vtag)
if git_semver['prerelease'] is None or git_semver['prerelease'] == '':
git_since_vtag = git.run(
'rev-list ' + git_last_vtag + '.. --count')
if int(git_since_vtag) > 0:
git_semver['tweak'] = int(git_since_vtag)
else:
git_semver['tweak'] = None
info = {'git_describe': git_describe, 'git_timestamp': git_timestamp,
'git_tree': git_tree, 'git_commit': git_commit, 'semver': semver_string(git_semver)}
return info
def export_sources(self):
subprocess.run(['make', '-C', self.recipe_folder, 'DIST_DIR=' +
self.export_sources_folder, '@dist-checked.tag'], check=True)
rm(self, 'Makefile', self.export_sources_folder)
rm(self, 'GNUmakefile', self.export_sources_folder)
# json.dump(self.fetch_versioninfo_from_git(), open(os.path.join(
# self.export_sources_folder, 'VERSION.json'), 'w', encoding='utf-8'))
def source(self):
version_json_pathname = os.path.join(
self.export_sources_folder, 'VERSION.json')
version_json = json.load(
open(os.path.join(version_json_pathname), encoding='utf-8'))['semver']
if version_json != semver_string(semver_parse(self.version)):
self.output.error('Package/Recipe version "' + self.version +
'" mismatch VERSION.json "' + version_json + '"')
def set_version(self):
if self.build_metadata is None and not self.version is None:
self.build_metadata = self.version
semver = semver_parse(self.build_metadata)
if semver:
self.build_metadata = semver['buildmetadata']
else:
self.build_metadata = re.match(
'^[^0-9a-zA-Z]*([0-9a-zA-Z]+[-.0-9a-zA-Z]*)', self.build_metadata).group(1)
if self.build_metadata is None:
self.build_metadata = ''
version_json_pathname = os.path.join(
self.recipe_folder, 'VERSION.json')
if os.path.exists(version_json_pathname):
self.version = json.load(
open(version_json_pathname, encoding='utf-8'))['semver']
version_from = "'" + version_jsonpath_name + "'"
else:
self.version = self.fetch_versioninfo_from_git()['semver']
version_from = 'Git'
self.output.verbose('Fetch version from ' +
version_from + ': ' + self.version)
if self.build_metadata != '':
self.version += '+' + self.build_metadata
def layout(self):
cmake_layout(self)
def handle_option(self, tc, name, define=False):
opt = self.options.get_safe(name)
if not opt is None:
value = str(opt).lower()
if value != 'auto' and value != 'default':
name = name.upper().replace('.', '_')
if define:
if value == 'false' or value == 'no' or value == 'off':
tc.preprocessor_definitions[name] = 0
elif value == 'true' or value == 'yes' or value == 'on':
tc.preprocessor_definitions[name] = 1
else:
tc.preprocessor_definitions[name] = int(opt)
self.output.highlight(
name + '=' + str(tc.preprocessor_definitions[name]) + ' (' + str(opt) + ')')
else:
tc.cache_variables[name] = opt
self.output.highlight(
name + '=' + str(tc.cache_variables[name]) + ' (' + str(opt) + ')')
def generate(self):
tc = CMakeToolchain(self)
if self.build_metadata is None:
self.build_metadata = semver_parse(self.version)['buildmetadata']
if not self.build_metadata is None and self.build_metadata != '':
tc.variables['MDBX_BUILD_METADATA'] = self.build_metadata
self.output.highlight('MDBX_BUILD_METADATA is ' +
str(tc.variables['MDBX_BUILD_METADATA']))
self.handle_option(tc, 'mdbx.64bit_atomic', True)
self.handle_option(tc, 'mdbx.64bit_cas', True)
self.handle_option(tc, 'mdbx.apple.speed_insteadof_durability')
self.handle_option(tc, 'mdbx.avoid_msync')
self.handle_option(tc, 'mdbx.build_tools')
self.handle_option(tc, 'mdbx.build_cxx')
self.handle_option(tc, 'mdbx.cacheline_size', True)
self.handle_option(tc, 'mdbx.disable_validation')
self.handle_option(tc, 'mdbx.enable_bigfoot')
self.handle_option(tc, 'mdbx.enable_dbi_lockfree')
self.handle_option(tc, 'mdbx.enable_dbi_sparse')
self.handle_option(tc, 'mdbx.enable_pgop_stat')
self.handle_option(tc, 'mdbx.enable_profgc')
self.handle_option(tc, 'mdbx.enable_refund')
self.handle_option(tc, 'mdbx.env_checkpid')
self.handle_option(tc, 'mdbx.force_assertions')
self.handle_option(tc, 'mdbx.have_builtin_cpu_supports', True)
self.handle_option(tc, 'mdbx.mmap_incoherent_file_write', True)
self.handle_option(tc, 'mdbx.mmap_needs_jolt')
self.handle_option(tc, 'mdbx.trust_rtc')
self.handle_option(tc, 'mdbx.txn_checkowner')
self.handle_option(tc, 'mdbx.unaligned_ok', True)
self.handle_option(tc, 'mdbx.use_copyfilerange', True)
self.handle_option(tc, 'mdbx.use_mincore')
self.handle_option(tc, 'mdbx.use_ofdlocks')
self.handle_option(tc, 'mdbx.use_sendfile', True)
self.handle_option(tc, 'mdbx.without_msvc_crt')
opt = self.options.get_safe('mdbx.locking', 'auto')
if not opt is None:
value = str(opt).lower()
if value != 'auto' and value != 'default':
map = {'windowsfilelocking': -1, 'systemv': 5, 'posix1988': 1988,
'posix2001': 2001, 'posix2008': 2008}
value = map[value]
tc.cache_variables['MDBX_LOCKING'] = value
self.output.highlight('MDBX_LOCKING=' +
str(tc.cache_variables['MDBX_LOCKING']))
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
if self.options.shared:
self.cpp_info.libs = ['mdbx']
else:
self.cpp_info.libs = ['mdbx-static']