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


roscompile
Author(s):
autogenerated on Wed Mar 3 2021 03:56:01