Package roswtf :: Module packages
[frames] | no frames]

Source Code for Module roswtf.packages

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2009, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32  # 
 33  # Revision $Id$ 
 34   
 35  import os 
 36  import time 
 37   
 38  from roswtf.environment import paths, is_executable 
 39  from roswtf.rules import warning_rule, error_rule 
 40   
 41  import roslib.msgs 
 42  import roslib.srvs 
 43  from roslib.packages import get_pkg_dir, InvalidROSPkgException, PACKAGE_FILE 
 44   
 45  ## look for unknown tags in manifest 
46 -def manifest_valid(ctx):
47 errors = [] 48 if ctx.manifest is not None: 49 errors = ["<%s>"%t.tagName for t in ctx.manifest.unknown_tags] 50 return errors
51
52 -def _manifest_msg_srv_export(ctx, type_):
53 exist = [] 54 for pkg in ctx.pkgs: 55 pkg_dir = roslib.packages.get_pkg_dir(pkg) 56 d = os.path.join(pkg_dir, type_) 57 if os.path.isdir(d): 58 files = os.listdir(d) 59 if filter(lambda x: x.endswith('.'+type_), files): 60 try: 61 m_file = roslib.manifest.manifest_file(pkg, True) 62 except InvalidROSPkgException: 63 # ignore wet package from further investigation 64 env = os.environ 65 pkg_path = get_pkg_dir(pkg, True, ros_root=env['ROS_ROOT']) 66 if os.path.exists(os.path.join(pkg_path, PACKAGE_FILE)): 67 continue 68 raise 69 m = roslib.manifest.parse_file(m_file) 70 cflags = m.get_export('cpp', 'cflags') 71 include = '-I${prefix}/%s/cpp'%type_ 72 if filter(lambda x: include in x, cflags): 73 exist.append(pkg) 74 return exist
75
76 -def manifest_msg_srv_export(ctx):
77 msgs = set(_manifest_msg_srv_export(ctx, 'msg')) 78 srvs = set(_manifest_msg_srv_export(ctx, 'srv')) 79 errors = [] 80 81 for pkg in msgs & srvs: 82 errors.append('%s: -I${prefix}/msg/cpp -I${prefix}/srv/cpp'%pkg) 83 for pkg in msgs - srvs: 84 errors.append('%s: -I${prefix}/msg/cpp'%pkg) 85 for pkg in srvs - msgs: 86 errors.append('%s: -I${prefix}/srv/cpp'%pkg) 87 return errors
88 89
90 -def _check_for_rpath_flags(pkg, lflags):
91 if not lflags: 92 return 93 L_arg = '-L' 94 Wl_arg = '-Wl' 95 rpath_arg = '-rpath' 96 lflags_args = lflags.split() 97 # Collect the args we care about 98 L_args = [] 99 rpath_args = [] 100 i = 0 101 while i < len(lflags_args): 102 f = lflags_args[i] 103 if f.startswith(L_arg) and len(f) > len(L_arg): 104 # normpath avoids problems with trailing slash vs. no trailing 105 # slash, #2284 106 L_args.append(os.path.normpath(f[len(L_arg):])) 107 elif f == L_arg and (i+1) < len(lflags_args): 108 i += 1 109 # normpath avoids problems with trailing slash vs. no trailing 110 # slash, #2284 111 L_args.append(os.path.normpath(lflags_args[i])) 112 elif f.startswith(Wl_arg) and len(f) > len(Wl_arg): 113 # -Wl can be followed by multiple, comma-separated arguments, 114 # #2284. 115 args = f.split(',') 116 j = 1 117 while j < (len(args) - 1): 118 if args[j] == rpath_arg: 119 # normpath avoids problems with trailing slash vs. no trailing 120 # slash, #2284 121 rpath_args.append(os.path.normpath(args[j+1])) 122 j += 2 123 else: 124 j += 1 125 i += 1 126 # Check for parallelism; not efficient, but these strings are short 127 for f in L_args: 128 if f not in rpath_args: 129 return '%s: found flag "-L%s", but no matching "-Wl,-rpath,%s"'%(pkg, f,f) 130 for f in rpath_args: 131 if f not in L_args: 132 return '%s: found flag "-Wl,-rpath,%s", but no matching "-L%s"'%(pkg, f,f)
133
134 -def manifest_rpath_flags(ctx):
135 warn = [] 136 for pkg in ctx.pkgs: 137 # Use rospack to get lflags, so that they can be bash-expanded 138 # first, #2286. 139 import subprocess 140 lflags = subprocess.Popen(['rospack', 'export', '--lang=cpp', '--attrib=lflags', pkg], stdout=subprocess.PIPE).communicate()[0] 141 err_msg = _check_for_rpath_flags(pkg, lflags) 142 if err_msg: 143 warn.append(err_msg) 144 return warn
145
146 -def cmakelists_package_valid(ctx):
147 missing = [] 148 for pkg in ctx.pkgs: 149 found = False 150 pkg_dir = roslib.packages.get_pkg_dir(pkg) 151 p = os.path.join(pkg_dir, 'CMakeLists.txt') 152 if not os.path.isfile(p): 153 continue #covered by cmakelists_exists 154 f = open(p) 155 try: 156 for l in f: 157 # ignore all whitespace 158 l = l.strip().replace(' ', '') 159 160 if l.startswith('rospack('): 161 found = True 162 if not l.startswith('rospack(%s)'%pkg): 163 missing.append(pkg) 164 break 165 # there may be more than 1 rospack() declaration, so scan through entire 166 # CMakeLists 167 elif l.startswith("rosbuild_init()"): 168 found = True 169 finally: 170 f.close() 171 # rospack exists outside our build system 172 if 'rospack' in missing: 173 missing.remove('rospack') 174 return missing
175 176 warnings = [ 177 # disabling as it is too common and regular 178 (cmakelists_package_valid, 179 "The following packages have incorrect rospack() declarations in CMakeLists.txt.\nPlease switch to using rosbuild_init():"), 180 181 (manifest_msg_srv_export, 182 'The following packages have msg/srv-related cflags exports that are no longer necessary\n\t<export>\n\t\t<cpp cflags="..."\n\t</export>:'), 183 (manifest_valid, "%(pkg)s/manifest.xml has unrecognized tags:"), 184 185 ] 186 errors = [ 187 (manifest_rpath_flags, "The following packages have rpath issues in manifest.xml:"), 188 ] 189
190 -def wtf_check(ctx):
191 # no package in context to verify 192 if not ctx.pkgs: 193 return 194 195 for r in warnings: 196 warning_rule(r, r[0](ctx), ctx) 197 for r in errors: 198 error_rule(r, r[0](ctx), ctx)
199