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


roscompile
Author(s):
autogenerated on Tue Jun 21 2022 03:01:39