diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2019-07-31 18:40:15 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-31 18:40:15 +0300 |
commit | 679ddb0ae780bfd4d81c586b0512255c0d1e24b6 (patch) | |
tree | e5f472bb7a82f1f36c45969e9dd2aad65f7d832a /mesonbuild/cmake/traceparser.py | |
parent | 5d9a1558c2e1041b1149fca6b2bceba447b6823e (diff) | |
parent | 497fbf0ce096513957bf4eccd08a2cc942730b0c (diff) | |
download | meson-679ddb0ae780bfd4d81c586b0512255c0d1e24b6.zip meson-679ddb0ae780bfd4d81c586b0512255c0d1e24b6.tar.gz meson-679ddb0ae780bfd4d81c586b0512255c0d1e24b6.tar.bz2 |
Merge pull request #5638 from mensinda/cmInterface
CMake: Support INTERFACE libraries
Diffstat (limited to 'mesonbuild/cmake/traceparser.py')
-rw-r--r-- | mesonbuild/cmake/traceparser.py | 96 |
1 files changed, 84 insertions, 12 deletions
diff --git a/mesonbuild/cmake/traceparser.py b/mesonbuild/cmake/traceparser.py index 4b87319..6106d16 100644 --- a/mesonbuild/cmake/traceparser.py +++ b/mesonbuild/cmake/traceparser.py @@ -81,7 +81,11 @@ class CMakeTraceParser: 'add_custom_command': self._cmake_add_custom_command, 'add_custom_target': self._cmake_add_custom_target, 'set_property': self._cmake_set_property, - 'set_target_properties': self._cmake_set_target_properties + 'set_target_properties': self._cmake_set_target_properties, + 'target_compile_definitions': self._cmake_target_compile_definitions, + 'target_compile_options': self._cmake_target_compile_options, + 'target_include_directories': self._cmake_target_include_directories, + 'target_link_options': self._cmake_target_link_options, } # Primary pass -- parse everything @@ -199,16 +203,23 @@ class CMakeTraceParser: args = list(tline.args) # Make a working copy # Make sure the lib is imported - if 'IMPORTED' not in args: - return self._gen_exception('add_library', 'non imported libraries are not supported', tline) + if 'INTERFACE' in args: + args.remove('INTERFACE') - args.remove('IMPORTED') + if len(args) < 1: + return self._gen_exception('add_library', 'interface library name not specified', tline) - # No only look at the first two arguments (target_name and target_type) and ignore the rest - if len(args) < 2: - return self._gen_exception('add_library', 'requires at least 2 arguments', tline) + self.targets[args[0]] = CMakeTarget(args[0], 'INTERFACE', {}) + elif 'IMPORTED' in args: + args.remove('IMPORTED') - self.targets[args[0]] = CMakeTarget(args[0], args[1], {}) + # No only look at the first two arguments (target_name and target_type) and ignore the rest + if len(args) < 2: + return self._gen_exception('add_library', 'requires at least 2 arguments', tline) + + self.targets[args[0]] = CMakeTarget(args[0], args[1], {}) + else: + return self._gen_exception('add_library', 'non imported / interface libraries are not supported', tline) def _cmake_add_custom_command(self, tline: CMakeTraceLine): # DOC: https://cmake.org/cmake/help/latest/command/add_custom_command.html @@ -343,8 +354,8 @@ class CMakeTraceParser: # set_property() this is not context free. There are two approaches I # can think of, both have drawbacks: # - # 1. Assume that the property will be capitalized, this is convention - # but cmake doesn't require it. + # 1. Assume that the property will be capitalized ([A-Z_]), this is + # convention but cmake doesn't require it. # 2. Maintain a copy of the list here: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#target-properties # # Neither of these is awesome for obvious reasons. I'm going to try @@ -354,8 +365,9 @@ class CMakeTraceParser: arglist = [] # type: List[Tuple[str, List[str]]] name = args.pop(0) values = [] + prop_regex = re.compile(r'^[A-Z_]+$') for a in args: - if a.isupper(): + if prop_regex.match(a): if values: arglist.append((name, ' '.join(values).split(';'))) name = a @@ -372,6 +384,66 @@ class CMakeTraceParser: self.targets[i].properies[name] = value + def _cmake_target_compile_definitions(self, tline: CMakeTraceLine) -> None: + # DOC: https://cmake.org/cmake/help/latest/command/target_compile_definitions.html + self._parse_common_target_options('target_compile_definitions', 'COMPILE_DEFINITIONS', 'INTERFACE_COMPILE_DEFINITIONS', tline) + + def _cmake_target_compile_options(self, tline: CMakeTraceLine) -> None: + # DOC: https://cmake.org/cmake/help/latest/command/target_compile_options.html + self._parse_common_target_options('target_compile_options', 'COMPILE_OPTIONS', 'INTERFACE_COMPILE_OPTIONS', tline) + + def _cmake_target_include_directories(self, tline: CMakeTraceLine) -> None: + # DOC: https://cmake.org/cmake/help/latest/command/target_include_directories.html + self._parse_common_target_options('target_include_directories', 'INCLUDE_DIRECTORIES', 'INTERFACE_INCLUDE_DIRECTORIES', tline, ignore=['SYSTEM', 'BEFORE'], paths=True) + + def _cmake_target_link_options(self, tline: CMakeTraceLine) -> None: + # DOC: https://cmake.org/cmake/help/latest/command/target_link_options.html + self._parse_common_target_options('target_link_options', 'LINK_OPTIONS', 'INTERFACE_LINK_OPTIONS', tline) + + def _parse_common_target_options(self, func: str, private_prop: str, interface_prop: str, tline: CMakeTraceLine, ignore: Optional[List[str]] = None, paths: bool = False): + if ignore is None: + ignore = ['BEFORE'] + + args = list(tline.args) + + if len(args) < 1: + return self._gen_exception(func, 'requires at least one argument', tline) + + target = args[0] + if target not in self.targets: + return self._gen_exception(func, 'TARGET {} not found'.format(target), tline) + + interface = [] + private = [] + + mode = 'PUBLIC' + for i in args[1:]: + if i in ignore: + continue + + if i in ['INTERFACE', 'PUBLIC', 'PRIVATE']: + mode = i + continue + + if mode in ['INTERFACE', 'PUBLIC']: + interface += [i] + + if mode in ['PUBLIC', 'PRIVATE']: + private += [i] + + if paths: + interface = self._guess_files(interface) + private = self._guess_files(private) + + interface = [x for x in interface if x] + private = [x for x in private if x] + + for i in [(private_prop, private), (interface_prop, interface)]: + if not i[0] in self.targets[target].properies: + self.targets[target].properies[i[0]] = [] + + self.targets[target].properies[i[0]] += i[1] + def _lex_trace(self, trace): # The trace format is: '<file>(<line>): <func>(<args -- can contain \n> )\n' reg_tline = re.compile(r'\s*(.*\.(cmake|txt))\(([0-9]+)\):\s*(\w+)\(([\s\S]*?) ?\)\s*\n', re.MULTILINE) @@ -420,7 +492,7 @@ class CMakeTraceParser: # Abort concatination if curr_str no longer matches the regex fixed_list += [curr_str] curr_str = i - elif reg_end.match(i): + elif reg_end.match(i) or os.path.exists('{} {}'.format(curr_str, i)): # File detected curr_str = '{} {}'.format(curr_str, i) fixed_list += [curr_str] |