cmake.py
Go to the documentation of this file.
1 from ros_introspection.cmake import Command, CommandGroup, get_sort_key
3 from ros_introspection.resource_list import is_message, is_service
4 from util import get_ignore_data, roscompile
5 
6 SHOULD_ALPHABETIZE = ['COMPONENTS', 'DEPENDENCIES', 'FILES', 'CATKIN_DEPENDS']
7 NEWLINE_PLUS_4 = '\n '
8 NEWLINE_PLUS_8 = '\n '
9 
10 
11 def check_cmake_dependencies_helper(cmake, dependencies, check_catkin_pkg=True):
12  if len(dependencies) == 0:
13  return
14  if len(cmake.content_map['find_package']) == 0:
15  cmd = Command('find_package')
16  cmd.add_section('', ['catkin'])
17  cmd.add_section('REQUIRED')
18  cmake.add_command(cmd)
19 
20  for cmd in cmake.content_map['find_package']:
21  tokens = cmd.get_tokens()
22  if tokens and tokens[0] == 'catkin' and cmd.get_section('REQUIRED'):
23  req_sec = cmd.get_section('REQUIRED')
24  section = cmd.get_section('COMPONENTS')
25  if section is None and req_sec.values:
26  section = req_sec # Allow packages to be listed without COMPONENTS keyword
27  if section is None:
28  cmd.add_section('COMPONENTS', sorted(dependencies))
29  else:
30  existing = cmake.resolve_variables(section.values)
31  needed_items = dependencies - set(existing)
32  if len(needed_items) > 0:
33  section.values += list(sorted(needed_items))
34  cmd.changed = True
35  if check_catkin_pkg:
36  cmake.section_check(dependencies, 'catkin_package', 'CATKIN_DEPENDS')
37 
38 
39 @roscompile
41  dependencies = package.get_dependencies_from_msgs()
42  dependencies.update(package.get_build_dependencies())
43  check_cmake_dependencies_helper(package.cmake, dependencies)
44 
45 
46 def get_matching_add_depends(cmake, search_target):
47  valid_targets = set([search_target])
48  alt_target = cmake.resolve_variables(search_target)
49  if alt_target != search_target:
50  valid_targets.add(alt_target)
51 
52  for cmd in cmake.content_map['add_dependencies']:
53  target = cmd.first_token()
54  if target in valid_targets:
55  return cmd
56  resolved_target = cmake.resolve_variables(target)
57  if resolved_target in valid_targets:
58  return cmd
59 
60 
61 def match_generator_name(package, name):
62  for gen in package.get_all_generators():
63  if name == gen.base_name:
64  return gen
65 
66 
67 def get_msg_dependencies_from_source(package, sources):
68  deps = set()
69  for rel_fn in sources:
70  if rel_fn not in package.source_code.sources:
71  continue
72  src = package.source_code.sources[rel_fn]
73  for pkg, name in src.search_lines_for_pattern(CPLUS):
74  if len(name) == 0 or name[-2:] != '.h':
75  continue
76  name = name.replace('.h', '')
77  if is_message(pkg, name) or is_service(pkg, name):
78  deps.add(pkg)
79  elif pkg == package.name and match_generator_name(package, name):
80  deps.add(pkg)
81  if package.dynamic_reconfigs:
82  deps.add(package.name)
83  return sorted(list(deps))
84 
85 
86 @roscompile
88  targets = package.cmake.get_target_build_rules()
89  for target, sources in targets.iteritems():
90  deps = get_msg_dependencies_from_source(package, sources)
91  if len(deps) == 0:
92  continue
93 
94  if package.name in deps:
95  self_depend = True
96  if len(deps) == 1:
97  cat_depend = False
98  else:
99  cat_depend = True
100  else:
101  self_depend = False
102  cat_depend = True
103 
104  add_deps = get_matching_add_depends(package.cmake, target)
105  add_add_deps = False
106 
107  if add_deps is None:
108  add_deps = Command('add_dependencies')
109  add_add_deps = True # Need to wait to add the command for proper sorting
110 
111  if len(add_deps.sections) == 0:
112  add_deps.add_section('', [target])
113  add_deps.changed = True
114 
115  section = add_deps.sections[0]
116  if cat_depend and '${catkin_EXPORTED_TARGETS}' not in section.values:
117  section.add('${catkin_EXPORTED_TARGETS}')
118  add_deps.changed = True
119  if self_depend:
120  tokens = [package.cmake.resolve_variables(s) for s in section.values]
121  key = '${%s_EXPORTED_TARGETS}' % package.name
122  if key not in tokens:
123  section.add(key)
124  add_deps.changed = True
125 
126  if add_add_deps:
127  package.cmake.add_command(add_deps)
128 
129 
130 def remove_pattern(section, pattern):
131  prev_len = len(section.values)
132  section.values = [v for v in section.values if pattern not in v]
133  return prev_len != len(section.values)
134 
135 
136 @roscompile
138  global_changed = False
139  targets = package.cmake.get_target_build_rules()
140  for target, sources in targets.iteritems():
141  add_deps = get_matching_add_depends(package.cmake, target)
142  if add_deps is None or len(add_deps.sections) == 0:
143  continue
144 
145  section = add_deps.sections[0]
146  changed = remove_pattern(section, '_generate_messages_cpp')
147  changed = remove_pattern(section, '_gencpp') or changed
148  changed = remove_pattern(section, '_gencfg') or changed
149  if changed:
150  add_deps.changed = True
151  global_changed = True
152  if global_changed:
154 
155 
156 @roscompile
158  CATKIN = '${catkin_LIBRARIES}'
159  targets = package.cmake.get_libraries() + package.cmake.get_executables()
160  for cmd in package.cmake.content_map['target_link_libraries']:
161  tokens = cmd.get_tokens()
162  if tokens[0] in targets:
163  if CATKIN not in tokens:
164  print('\tAdding %s to target_link_libraries for %s' % (CATKIN, tokens[0]))
165  cmd.add_token(CATKIN)
166  targets.remove(tokens[0])
167  continue
168  for target in targets:
169  print('\tAdding target_link_libraries for %s' % target)
170  cmd = Command('target_link_libraries')
171  cmd.add_section('', [target, CATKIN])
172  package.cmake.add_command(cmd)
173 
174 
175 @roscompile
176 def check_generators(package):
177  if len(package.generators) == 0:
178  return
179 
180  for gen_type, cmake_cmd in [('msg', 'add_message_files'),
181  ('srv', 'add_service_files'),
182  ('action', 'add_action_files')]:
183  names = [gen.name for gen in package.generators[gen_type]]
184  package.cmake.section_check(names, cmake_cmd, 'FILES')
185 
186  package.cmake.section_check(['message_generation'], 'find_package', 'COMPONENTS')
187  package.cmake.section_check(['message_runtime'], 'catkin_package', 'CATKIN_DEPENDS')
188  for cmd in package.cmake.content_map['catkin_package']:
189  section = cmd.get_section('CATKIN_DEPENDS')
190  if 'message_generation' in section.values:
191  section.values.remove('message_generation')
192  cmd.changed = True
193 
194  msg_deps = package.get_dependencies_from_msgs()
195  if msg_deps:
196  package.cmake.section_check(msg_deps, 'generate_messages',
197  'DEPENDENCIES', zero_okay=True)
198  else:
199  package.cmake.section_check(msg_deps, 'generate_messages',
200  zero_okay=True)
201 
202 
203 @roscompile
204 def check_includes(package):
205  has_includes = False
206  if package.source_code.has_header_files():
207  package.cmake.section_check(['include'], 'catkin_package', 'INCLUDE_DIRS')
208  package.cmake.section_check(['include'], 'include_directories')
209  has_includes = True
210 
211  if len(package.source_code.get_source_by_language('c++')) > 0:
212  package.cmake.section_check(['${catkin_INCLUDE_DIRS}'], 'include_directories')
213  has_includes = True
214 
215  if not has_includes and 'include_directories' in package.cmake.content_map:
216  for cmd in package.cmake.content_map['include_directories']:
217  package.cmake.remove_command(cmd)
218 
219 
220 @roscompile
221 def check_library_setup(package):
222  package.cmake.section_check(package.cmake.get_libraries(), 'catkin_package', 'LIBRARIES')
223 
224 
226  for content in cmake.contents:
227  if content.__class__ == Command:
228  for section in content.get_real_sections():
229  if section.name in SHOULD_ALPHABETIZE:
230  sorted_values = list(sorted(section.values))
231  if sorted_values != section.values:
232  section.values = sorted_values
233  content.changed = True
234  elif content.__class__ == CommandGroup:
235  alphabetize_sections_helper(content.sub)
236 
237 
238 @roscompile
239 def alphabetize_sections(package):
240  alphabetize_sections_helper(package.cmake)
241 
242 
243 @roscompile
245  for cmd in package.cmake.content_map['catkin_package']:
246  for section in cmd.get_real_sections():
247  section.style.prename = NEWLINE_PLUS_4
248  cmd.changed = True
249 
250 
251 @roscompile
253  acceptable_styles = [(NEWLINE_PLUS_8, NEWLINE_PLUS_8), (NEWLINE_PLUS_4, NEWLINE_PLUS_8)]
254 
255  for cmd_name, section_name in [('find_package', 'COMPONENTS'), ('catkin_package', 'CATKIN_DEPENDS')]:
256  for cmd in package.cmake.content_map[cmd_name]:
257  for section in cmd.get_real_sections():
258  if section.name != section_name:
259  continue
260  n = len(str(section))
261  if n > 120:
262  key = section.style.name_val_sep, section.style.val_sep
263  if key not in acceptable_styles:
264  section.style.name_val_sep = NEWLINE_PLUS_4
265  section.style.val_sep = NEWLINE_PLUS_8
266  cmd.changed = True
267 
268 
269 @roscompile
270 def prettify_msgs_srvs(package):
271  for cmd in package.cmake.content_map['add_message_files'] + package.cmake.content_map['add_service_files']:
272  for section in cmd.get_real_sections():
273  if len(section.values) > 1:
274  section.style.name_val_sep = NEWLINE_PLUS_4
275  section.style.val_sep = NEWLINE_PLUS_4
276  cmd.changed = True
277 
278 
279 @roscompile
280 def prettify_installs(package):
281  for cmd in package.cmake.content_map['install']:
282  cmd.changed = True
283  cmd.sections = [s for s in cmd.sections if type(s) != str]
284  zeroed = False
285  for section in cmd.sections[1:]:
286  if len(section.values) == 0:
287  section.style.prename = NEWLINE_PLUS_8
288  zeroed = True
289  elif not zeroed:
290  section.style.prename = NEWLINE_PLUS_8
291  else:
292  section.style.prename = ''
293 
294 
296  return filter(lambda x: x != '', a)
297 
298 
299 def remove_cmake_command_comments_helper(command, ignorables, replacement=''):
300  for i, section in enumerate(command.sections):
301  if type(section) != str:
302  continue
303  for ignorable in ignorables:
304  while ignorable in command.sections[i]:
305  command.changed = True
306  command.sections[i] = command.sections[i].replace(ignorable, replacement)
307  if command.changed:
308  command.sections = remove_empty_strings(command.sections)
309  if command.sections == ['\n']:
310  command.sections = []
311 
312 
313 def remove_cmake_comments_helper(cmake, ignorables, replacement=''):
314  for i, content in enumerate(cmake.contents):
315  if content.__class__ == Command:
316  remove_cmake_command_comments_helper(content, ignorables, replacement)
317  elif content.__class__ == CommandGroup:
318  remove_cmake_comments_helper(content.sub, ignorables, replacement)
319  else:
320  for ignorable in ignorables:
321  while ignorable in cmake.contents[i]:
322  cmake.contents[i] = cmake.contents[i].replace(ignorable, replacement)
323  cmake.contents = remove_empty_strings(cmake.contents)
324 
325 
326 @roscompile
328  ignorables = get_ignore_data('cmake', {'package': package.name})
329  remove_cmake_comments_helper(package.cmake, ignorables)
330  remove_empty_cmake_lines(package)
331 
332 
333 @roscompile
335  for i, content in enumerate(package.cmake.contents[:-2]):
336  if str(content)[-1] == '\n' and package.cmake.contents[i + 1] == '\n' and package.cmake.contents[i + 2] == '\n':
337  package.cmake.contents[i + 1] = ''
338  package.cmake.contents = remove_empty_strings(package.cmake.contents)
339 
340 
342  anchors = cmake.get_ordered_build_targets()
343  clusters = []
344  current = []
345  for content in cmake.contents:
346  current.append(content)
347  if type(content) == str:
348  continue
349  key = get_sort_key(content, anchors)
350  clusters.append((key, current))
351  current = []
352  if len(current) > 0:
353  clusters.append((get_sort_key(None, anchors), current))
354 
355  return sorted(clusters, key=lambda kv: kv[0])
356 
357 
359  clusters = get_cmake_clusters(cmake)
360  cmake.contents = []
361  for key, contents in clusters:
362  cmake.contents += contents
363 
364 
365 @roscompile
367  enforce_cmake_ordering_helper(package.cmake)
368  for group in package.cmake.content_map['group']:
def check_cmake_dependencies(package)
Definition: cmake.py:40
def remove_empty_strings(a)
Definition: cmake.py:295
def check_includes(package)
Definition: cmake.py:204
def check_generators(package)
Definition: cmake.py:176
def remove_old_style_cpp_dependencies(package)
Definition: cmake.py:137
def prettify_msgs_srvs(package)
Definition: cmake.py:270
def prettify_package_lists(package)
Definition: cmake.py:252
def get_ignore_data(name, variables=None, add_newline=True)
Definition: util.py:32
def remove_boilerplate_cmake_comments(package)
Definition: cmake.py:327
def check_cmake_dependencies_helper(cmake, dependencies, check_catkin_pkg=True)
Definition: cmake.py:11
def prettify_catkin_package_cmd(package)
Definition: cmake.py:244
def remove_empty_cmake_lines(package)
Definition: cmake.py:334
def get_matching_add_depends(cmake, search_target)
Definition: cmake.py:46
def enforce_cmake_ordering(package)
Definition: cmake.py:366
def remove_cmake_comments_helper(cmake, ignorables, replacement='')
Definition: cmake.py:313
def target_catkin_libraries(package)
Definition: cmake.py:157
def get_cmake_clusters(cmake)
Definition: cmake.py:341
def enforce_cmake_ordering_helper(cmake)
Definition: cmake.py:358
def alphabetize_sections(package)
Definition: cmake.py:239
def alphabetize_sections_helper(cmake)
Definition: cmake.py:225
def remove_pattern(section, pattern)
Definition: cmake.py:130
def get_msg_dependencies_from_source(package, sources)
Definition: cmake.py:67
def match_generator_name(package, name)
Definition: cmake.py:61
def check_library_setup(package)
Definition: cmake.py:221
def prettify_installs(package)
Definition: cmake.py:280
def check_exported_dependencies(package)
Definition: cmake.py:87
def remove_cmake_command_comments_helper(command, ignorables, replacement='')
Definition: cmake.py:299


roscompile
Author(s):
autogenerated on Wed Jun 19 2019 19:56:53