Skip to content

Commit 280a856

Browse files
committed
Allow conditional features to use regex matching.
1 parent a4a99f0 commit 280a856

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

src/faber/artefacts/python.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ..feature import set
1010
from ..artefacts.library import library
11-
from ..tools.compiler import link
11+
from ..tools.compiler import link, ldflags
1212
from ..tools.python import python
1313
from os.path import join, normpath
1414

@@ -19,7 +19,10 @@ def __init__(self, *args, **kwds):
1919
library.__init__(self, *args, **kwds)
2020
p = python.instance(self.features)
2121
self.features |= set(p.include, p.linkpath, link('shared'))
22+
# on windows we need to link with libpython
2223
self.features |= p.libs(condition=(set.cc.name=='msvc')|(set.cxx.name=='msvc'))
24+
# on darwin we need to add `-undefined dynamic_lookup` to prevent undefined symbols errors
25+
self.features |= ldflags('-undefined dynamic_lookup', condition=(set.target.os.matches('darwin.*')))
2326
self._suffix = p.ext_suffix
2427

2528
@property

src/faber/feature/condition.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt)
88

99
import operator
10+
import re
1011

1112

1213
def contains(op1, op2):
@@ -15,6 +16,12 @@ def contains(op1, op2):
1516
return False if isinstance(op1, false) else operator.contains(op1, op2)
1617

1718

19+
def matches(op1, op2):
20+
# allow op1 to be `false`, so `set.nonexistent.match('x')`
21+
# becomes a valid expression
22+
return False if isinstance(op1, false) else re.match(op2, str(op1))
23+
24+
1825
class expr(object):
1926

2027
# we can't overload __not__ as that has to return a bool...
@@ -30,6 +37,7 @@ def contains(self, other): return binary(contains, self, other)
3037
def __bool__(self): raise ValueError('invalid expression "{}" !'.format(self))
3138
def __nonzero__(self): return self.__bool__()
3239
def __call__(self, ctx): return True
40+
def matches(self, other): return binary(matches, self, other)
3341

3442

3543
class true(expr):

tests/test_feature.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,14 @@ def test_delayed():
284284
fs.eval()
285285
assert fs.define == ('MACRO', 'SHARED', 'GXX', 'CXX')
286286
assert fs.include == ('a', 'b', '/some/path',)
287+
288+
289+
def test_condition():
290+
291+
tool = feature('tool', feature('name', sub=True), feature('version', sub=True))
292+
target = feature('target', feature('os', sub=True), feature('arch', sub=True))
293+
define = feature('define', attributes=multi)
294+
fs = set(tool(name='g++', version='6.3'), target(os='gnu-linux', arch='x86_64'))
295+
fs += define('LINUX', condition=set.target.os.matches('.*-linux'))
296+
fs.eval()
297+
assert fs.define == ('LINUX',)

0 commit comments

Comments
 (0)