rosboost_cfg.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Software License Agreement (BSD License)
3 #
4 # Copyright (c) 2010, Willow Garage, Inc.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 # * Neither the name of Willow Garage, Inc. nor the names of its
18 # contributors may be used to endorse or promote products derived
19 # from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 
34 from __future__ import print_function
35 
36 import sys
37 import os
38 import string
39 from glob import glob
40 import subprocess
41 import platform
42 from optparse import OptionParser
43 
44 lib_suffix = "so"
45 if (sys.platform == "darwin"):
46  lib_suffix = "dylib"
47 
48 link_static = 'ROS_BOOST_LINK' in os.environ and os.environ['ROS_BOOST_LINK'] == "static"
49 if (link_static):
50  lib_suffix = "a"
51 
52 no_L_or_I = 'ROS_BOOST_NO_L_OR_I' in os.environ
53 
54 boost_version = None
55 if ('ROS_BOOST_VERSION' in os.environ and len(os.environ['ROS_BOOST_VERSION']) > 0):
56  ver = os.environ['ROS_BOOST_VERSION']
57  ver = ver.split('.')
58 
59  boost_version = [int(v) for v in ver]
60  if (len(boost_version) == 2):
61  boost_version.append(0)
62 
64  print("Usage: rosboost-cfg --lflags [thread,regex,graph,...]")
65  print(" rosboost-cfg --cflags")
66  print(" rosboost-cfg --libs [thread,regex,graph,...]")
67  print(" rosboost-cfg --include_dirs")
68  print(" rosboost-cfg --lib_dirs")
69  print(" rosboost-cfg --root")
70  sys.exit(1)
71 
72 class BoostError(Exception):
73  def __init__(self, value):
74  self.value = value
75  def __str__(self):
76  return repr(self.value)
77 
78 class Version(object):
79  def __init__(self, major, minor, patch, root, include_dir, lib_dir, is_default_search_location):
80  self.major = major
81  self.minor = minor
82  self.patch = patch
83  self.root = root
84  self.include_dir = include_dir
85  self.lib_dir = lib_dir
86  self.is_default_search_location = is_default_search_location
87  self.is_system_install = os.path.split(self.include_dir)[0] == self.root
88 
89  def __cmp__(self, other):
90  if (self.major != other.major):
91  if self.major < other.major:
92  return -1
93  else:
94  return 1
95  if (self.minor != other.minor):
96  if self.minor < other.minor:
97  return -1
98  else:
99  return 1
100  if (self.patch != other.patch):
101  if self.patch < other.patch:
102  return -1
103  else:
104  return 1
105 
106  return 0
107  def __repr__(self):
108  return repr((self.major, self.minor, self.patch, self.root, self.include_dir, self.is_default_search_location, self.is_system_install))
109 
110 def find_lib_dir(root_dir, multiarch=''):
111  # prefer lib64 unless explicitly specified in the environment
112  if ('ROS_BOOST_LIB_DIR_NAME' in os.environ):
113  possible_dirs = [os.path.join(root_dir, os.environ['ROS_BOOST_LIB_DIR_NAME'])]
114  else:
115  possible_dirs = [os.path.join(root_dir, "lib64"), os.path.join(root_dir, "lib")]
116  if multiarch:
117  possible_dirs = [os.path.join(root_dir, "lib/%s" % multiarch)] + possible_dirs
118 
119  for p in possible_dirs:
120  glob_files = glob("%s*"%(os.path.join(p, "libboost*")))
121  if (len(glob_files) > 0):
122  return p
123 
124  return None
125 
126 def extract_versions(dir, is_default_search_location, multiarch=''):
127  version_paths = [os.path.join(dir, "version.hpp"),
128  os.path.join(dir, "boost", "version.hpp")]
129  glob_dirs = glob("%s*"%(os.path.join(dir, "boost-")))
130  [version_paths.append(os.path.join(gdir, "boost", "version.hpp")) for gdir in glob_dirs]
131 
132  versions = []
133 
134  for p in version_paths:
135  ver_string = ""
136  if (os.path.isfile(p)):
137  fh = open(p,"r")
138  lines = fh.readlines()
139  fh.close()
140  for line in lines:
141  if line.find("#define BOOST_VERSION ") > -1:
142  def_string = line.split()
143  ver_string = def_string[2]
144  ver_int = int(ver_string)
145  patch = ver_int % 100
146  minor = ver_int / 100 % 1000
147  major = ver_int / 100000
148  include_dir = os.path.split(os.path.split(p)[0])[0]
149  root_dir = os.path.split(dir)[0]
150  lib_dir = find_lib_dir(root_dir, multiarch)
151  versions.append(Version(major, minor, patch, root_dir, include_dir, lib_dir, is_default_search_location))
152 
153  return versions
154 
155 def find_versions(search_paths, multiarch=''):
156  vers = []
157 
158  for path, system in search_paths:
159  path = os.path.join(path, "include")
160  pvers = extract_versions(path, system, multiarch)
161  [vers.append(ver) for ver in pvers]
162 
163  if (len(vers) == 0):
164  return None
165 
166  if (boost_version is not None):
167  for v in vers:
168  if (v.major == boost_version[0] and v.minor == boost_version[1] and v.patch == boost_version[2]):
169  return [v]
170 
171  raise BoostError('Could not find boost version %s required by ROS_BOOST_VERSION environment variable'%(boost_version))
172 
173  vers.sort()
174  return vers
175 
176 def find_boost(search_paths, multiarch=''):
177  result = find_versions(search_paths, multiarch)
178  if result is None:
179  return None
180  if len(result) > 1:
181  sys.stderr.write("WARN, found multiple boost versions '%s', using latest"%result)
182  return result[-1]
183 
184 def search_paths(sysroot):
185  _search_paths = [(sysroot+'/usr', True),
186  (sysroot+'/usr/local', True),
187  (None if 'INCLUDE_DIRS' not in os.environ else os.environ['INCLUDE_DIRS'], True),
188  (None if 'CPATH' not in os.environ else os.environ['CPATH'], True),
189  (None if 'C_INCLUDE_PATH' not in os.environ else os.environ['C_INCLUDE_PATH'], True),
190  (None if 'CPLUS_INCLUDE_PATH' not in os.environ else os.environ['CPLUS_INCLUDE_PATH'], True),
191  (None if 'ROS_BOOST_ROOT' not in os.environ else os.environ['ROS_BOOST_ROOT'], False)]
192 
193  search_paths = []
194  for (str, system) in _search_paths:
195  if (str is not None):
196  dirs = str.split(':')
197  for dir in dirs:
198  if (len(dir) > 0):
199  if (dir.endswith('/include')):
200  dir = dir[:-len('/include')]
201  search_paths.append((dir, system))
202  return search_paths
203 
204 def lib_dir(ver):
205  return ver.lib_dir
206 
207 def find_lib(ver, name, full_lib = link_static):
208  global lib_suffix
209  global link_static
210 
211  dynamic_search_paths = []
212  static_search_paths = []
213 
214  if (ver.is_system_install):
215  dynamic_search_paths = ["libboost_%s-mt.%s"%(name, lib_suffix),
216  "libboost_%s.%s"%(name, lib_suffix)]
217  static_search_paths = ["libboost_%s-mt.a"%(name),
218  "libboost_%s.a"%(name)]
219  else:
220  dynamic_search_paths = ["libboost_%s*%s_%s*.%s"%(name, ver.major, ver.minor, lib_suffix),
221  "libboost_%s-mt*.%s"%(name, lib_suffix),
222  "libboost_%s*.%s"%(name, lib_suffix)]
223  static_search_paths = ["libboost_%s*%s_%s*.a"%(name, ver.major, ver.minor),
224  "libboost_%s-mt*.a"%(name),
225  "libboost_%s*.a"%(name)]
226 
227  # Boost.Python needs some special handling on some systems (Karmic), since it may have per-python-version libs
228  if (name == "python"):
229  python_ver = platform.python_version().split('.')
230  dynamic_search_paths = ["libboost_%s-mt-py%s%s.%s"%(name, python_ver[0], python_ver[1], lib_suffix),
231  "libboost_%s-py%s%s.%s"%(name, python_ver[0], python_ver[1], lib_suffix)] + dynamic_search_paths
232  static_search_paths = ["libboost_%s-mt-py%s%s.a"%(name, python_ver[0], python_ver[1]),
233  "libboost_%s-py%s%s.a"%(name, python_ver[0], python_ver[1])] + static_search_paths
234 
235  search_paths = static_search_paths if link_static else dynamic_search_paths
236 
237  dir = lib_dir(ver)
238 
239  if dir is None:
240  raise BoostError('Could not locate library [%s], version %s'%(name, ver))
241 
242  for p in search_paths:
243  globstr = os.path.join(dir, p)
244  libs = glob(globstr)
245  if (len(libs) > 0):
246  if (full_lib):
247  return libs[0]
248  else:
249  return os.path.basename(libs[0])
250 
251  raise BoostError('Could not locate library [%s], version %s in lib directory [%s]'%(name, ver, dir))
252 
253 def include_dirs(ver, prefix = ''):
254  if ver.is_system_install or no_L_or_I:
255  return ""
256 
257  return " %s%s"%(prefix, ver.include_dir)
258 
259 def cflags(ver):
260  return include_dirs(ver, '-I')
261 
262 def lib_dir_flags(ver):
263  if not ver.is_default_search_location:
264  dir = lib_dir(ver)
265  return ' -L%s -Wl,-rpath,%s'%(dir, dir)
266 
267  return ''
268 
269 def lib_flags(ver, name):
270  lib = find_lib(ver, name)
271  if (link_static):
272  return ' %s'%(lib)
273  else:
274  # Cut off "lib" and extension (.so/.a/.dylib/etc.)
275  return ' -l%s'%(os.path.splitext(lib)[0][len('lib'):])
276 
277 def lflags(ver, libs):
278  s= lib_dir_flags(ver) + " "
279  for lib in libs:
280  s += lib_flags(ver, lib) + " "
281  return s
282 
283 def libs(ver, libs):
284  s = ""
285  for lib in libs:
286  s += find_lib(ver, lib, True) + " "
287  return s
288 
289 def lib_dirs(ver):
290  if (ver.is_default_search_location or no_L_or_I):
291  return ""
292 
293  return lib_dir(ver)
294 
295 OPTIONS = ['libs', 'include_dirs', 'lib_dirs', 'cflags', 'lflags', 'root', 'print_versions', 'version']
296 
297 def check_one_option(options, key):
298  for k in dir(options):
299  if (k in OPTIONS):
300  v = getattr(options, k)
301  if (k != key and v):
302  raise BoostError("Only one option (excepting sysroot) is allowed at a time")
303 
304 def main():
305  if (len(sys.argv) < 2):
307 
308  parser = OptionParser()
309  parser.add_option("-l", "--libs", dest="libs", type="string", help="")
310  parser.add_option("-i", "--include_dirs", dest="include_dirs", action="store_true", default=False, help="")
311  parser.add_option("-d", "--lib_dirs", dest="lib_dirs", action="store_true", help="")
312  parser.add_option("-c", "--cflags", dest="cflags", action="store_true", default=False, help="")
313  parser.add_option("-f", "--lflags", dest="lflags", type="string", help="")
314  parser.add_option("-r", "--root", dest="root", action="store_true", default=False, help="")
315  parser.add_option("-p", "--print_versions", dest="print_versions", action="store_true", default=False, help="")
316  parser.add_option("-v", "--version", dest="version", action="store_true", default=False, help="")
317  parser.add_option("-s", "--sysroot", dest="sysroot", type="string", default='', help="Location of the system root (usually toolchain root).")
318  parser.add_option("-m", "--multiarch", dest="multiarch", type="string", default='', help="Name of multiarch to search below 'lib' folder for libraries.")
319 
320  (options, args) = parser.parse_args()
321 
322  if (options.print_versions):
323  check_one_option(options, 'print_versions')
324  for ver in find_versions(search_paths(options.sysroot), options.multiarch):
325  print('%s.%s.%s root=%s include_dir=%s'%(ver.major, ver.minor, ver.patch, ver.root, ver.include_dir))
326  return
327 
328  ver = find_boost(search_paths(options.sysroot), options.multiarch)
329 
330  if ver is None:
331  raise BoostError("Cannot find boost in any of %s"%search_paths(options.sysroot))
332  sys.exit(0)
333 
334  if options.version:
335  check_one_option(options, 'version')
336  print('%s.%s.%s root=%s include_dir=%s'%(ver.major, ver.minor, ver.patch, ver.root, ver.include_dir))
337  return
338 
339  if ver.major < 1 or (ver.major == 1 and ver.minor < 37):
340  raise BoostError('Boost version %s.%s.%s does not meet the minimum requirements of boost 1.37.0'%(ver.major, ver.minor, ver.patch))
341 
342 
343 
344  output = ""
345  if (options.root):
346  check_one_option(options, 'root')
347  output = ver.root
348  elif (options.libs):
349  check_one_option(options, 'libs')
350  output = libs(ver, options.libs.split(','))
351  elif (options.include_dirs):
352  check_one_option(options, 'include_dirs')
353  output = include_dirs(ver)
354  elif (options.lib_dirs):
355  check_one_option(options, 'lib_dirs')
356  output = lib_dirs(ver)
357  elif (options.cflags):
358  check_one_option(options, 'cflags')
359  output = cflags(ver)
360  elif (options.lflags):
361  check_one_option(options, 'lflags')
362  output = lflags(ver, options.lflags.split(','))
363  else:
365 
366  print(output.strip())
367 
368 if __name__ == "__main__":
369  main()
370 
def check_one_option(options, key)
def lib_flags(ver, name)
def find_versions(search_paths, multiarch='')
def find_lib(ver, name, full_lib=link_static)
def extract_versions(dir, is_default_search_location, multiarch='')
def find_boost(search_paths, multiarch='')
def __init__(self, major, minor, patch, root, include_dir, lib_dir, is_default_search_location)
Definition: rosboost_cfg.py:79
def find_lib_dir(root_dir, multiarch='')
def include_dirs(ver, prefix='')


rosboost_cfg
Author(s): Josh Faust
autogenerated on Tue Apr 2 2019 02:14:12