blob: 1632ab61ffd8a867a459473c4ff1990785475bc4 [file] [log] [blame]
Alexander Afanasyeve83c0562016-12-24 10:20:41 -08001#! /usr/bin/env python
2# encoding: utf-8
3
4'''
5
6When using this tool, the wscript will look like:
7
8 def options(opt):
9 opt.load('compiler_cxx cryptopp')
10
11 def configure(conf):
12 conf.load('compiler_cxx cryptopp')
13 conf.check_cryptopp()
14
15 def build(bld):
16 bld(source='main.cpp', target='app', use='CRYPTOPP')
17
18Options are generated, in order to specify the location of cryptopp includes/libraries.
19
20
21'''
22import sys
23import re
24from waflib import Utils,Logs,Errors
25from waflib.Configure import conf
26CRYPTOPP_DIR = ['/usr', '/usr/local', '/opt/local', '/sw']
27CRYPTOPP_VERSION_FILE = 'config.h'
28
29CRYPTOPP_CHECK_FRAGMENT = '''
30#include "../../src/security/v1/cryptopp.hpp"
31#include <iostream>
32
33int
34main()
35{
36 using namespace CryptoPP;
37
38 std::string buffer = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
39 SHA256 hash;
40 StringSource(buffer, true, new HashFilter(hash, new FileSink(std::cout)));
41 StringSource(reinterpret_cast<const uint8_t*>(buffer.c_str()), buffer.size(),
42 true, new HashFilter(hash, new FileSink(std::cout)));
43}
44'''
45
46def options(opt):
47 opt.add_option('--with-cryptopp', type='string', default=None, dest='cryptopp_dir',
48 help='''Path to where CryptoPP is installed, e.g., /usr/local''')
49
50@conf
51def __cryptopp_get_version_file(self, dir):
52 try:
53 return self.root.find_dir(dir).find_node('%s/%s' % ('include/cryptopp',
54 CRYPTOPP_VERSION_FILE))
55 except:
56 return None
57
58@conf
59def __cryptopp_find_root_and_version_file(self, *k, **kw):
60 root = k and k[0] or kw.get('path', self.options.cryptopp_dir)
61
62 file = self.__cryptopp_get_version_file(root)
63 if root and file:
64 return (root, file)
65 for dir in CRYPTOPP_DIR:
66 file = self.__cryptopp_get_version_file(dir)
67 if file:
68 return (dir, file)
69
70 if root:
71 self.fatal('CryptoPP not found in %s' % root)
72 else:
73 self.fatal('CryptoPP not found, please provide a --with-cryptopp=PATH argument (see help)')
74
75@conf
76def check_cryptopp(self, *k, **kw):
77 if not self.env['CXX']:
78 self.fatal('Load a c++ compiler first, e.g., conf.load("compiler_cxx")')
79
80 var = kw.get('uselib_store', 'CRYPTOPP')
81 mandatory = kw.get('mandatory', True)
82
83 use = kw.get('use', 'PTHREAD')
84
85 self.start_msg('Checking Crypto++ lib')
86 (root, file) = self.__cryptopp_find_root_and_version_file(*k, **kw)
87
88 try:
89 txt = file.read()
90 re_version = re.compile('^#define\\s+CRYPTOPP_VERSION\\s+([0-9]+)', re.M)
91 match = re_version.search(txt)
92
93 if match:
94 self.env.CRYPTOPP_VERSION = match.group(1)
95 v = int(self.env.CRYPTOPP_VERSION)
96 (major, minor, patch) = (int(v / 100), int(v % 100 / 10), int(v % 10))
97 self.end_msg("%d.%d.%d" % (major, minor, patch))
98 else:
99 self.fatal('CryptoPP files are present, but are not recognizable')
100 except:
101 self.fatal('CryptoPP not found or is not usable')
102
103 isLibWorking = False
104 for defines in [[], ['CRYPTOPP_DISABLE_ASM']]:
105 try:
106 self.check_cxx(msg='Checking if CryptoPP library works',
107 fragment=CRYPTOPP_CHECK_FRAGMENT,
108 lib='cryptopp',
109 includes="%s/include" % root,
110 libpath="%s/lib" % root,
111 mandatory=True,
112 use=use,
113 defines=defines,
114 uselib_store=var)
115 isLibWorking = True
116 break
117 except:
118 # try another flags
119 pass
120
121 if mandatory and not isLibWorking:
122 self.fatal('CryptoPP is present, but is not usable')