| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- # Copyright 2022 Google LLC
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """
- Modify the CMakeLists.txt from LevelDb to staticly link Snappy compression
- support.
- """
- import argparse
- import dataclasses
- import os
- import pathlib
- import subprocess
- from typing import Iterable, Sequence
- def main() -> None:
- arg_parser = argparse.ArgumentParser()
- arg_parser.add_argument("--snappy-source-dir", required=True)
- arg_parser.add_argument("--snappy-binary-dir", required=True)
- arg_parser.add_argument("--additional-patch-file", required=False)
- parsed_args = arg_parser.parse_args()
- del arg_parser
- snappy_source_dir = pathlib.Path(parsed_args.snappy_source_dir)
- snappy_binary_dir = pathlib.Path(parsed_args.snappy_binary_dir)
- additional_patch_file = parsed_args.additional_patch_file
- del parsed_args
- cmakelists_txt_file = pathlib.Path("CMakeLists.txt")
- with cmakelists_txt_file.open("rt", encoding="utf8") as f:
- lines = tuple(f)
- patcher = CMakeListsPatcher(
- lines,
- os.path.abspath(__file__),
- snappy_source_dir,
- snappy_binary_dir,
- )
- patched_lines = tuple(patcher.patch())
- with cmakelists_txt_file.open("wt", encoding="utf8") as f:
- f.writelines(patched_lines)
- additional_patch_stamp = 'leveldb_additional_patch_stamp'
- if additional_patch_file and not os.path.exists(additional_patch_stamp):
- print("Applying patch %s" % additional_patch_file)
- subprocess.run(['git', 'apply', '-v', additional_patch_file],
- check=True)
- # Create a stamp file so the patch isn't applied twice.
- open(additional_patch_stamp, 'a').close()
- @dataclasses.dataclass(frozen=True)
- class LineComponents:
- full: str
- indent: str
- line: str
- eol: str
- class CMakeListsPatcher:
- SNAPPY_DETECT_LINE = \
- """check_library_exists(snappy snappy_compress "" HAVE_SNAPPY)"""
- SNAPPY_INCLUDE_LINE = \
- "target_include_directories(leveldb"
- SNAPPY_LINK_LINE = \
- "target_link_libraries(leveldb snappy)"
- def __init__(
- self,
- lines: Sequence[str],
- script_name: str,
- snappy_source_dir: pathlib.Path,
- snappy_binary_dir: pathlib.Path) -> None:
- self.i = 0
- self.lines = lines
- self.script_name = script_name
- self.snappy_source_dir_str = snappy_source_dir.as_posix()
- self.snappy_binary_dir_str = snappy_binary_dir.as_posix()
- def patch(self) -> Iterable[str]:
- while self.i < len(self.lines):
- full_line = self.lines[self.i]
- line = self._split_line(full_line)
- self.i += 1
- if line.line == self.SNAPPY_DETECT_LINE:
- yield from self._on_snappy_detect_line(line)
- elif line.line == self.SNAPPY_INCLUDE_LINE:
- yield full_line
- yield from self._on_leveldb_include_start()
- elif line.line == self.SNAPPY_LINK_LINE:
- yield from self._on_leveldb_snappy_link_line(line)
- else:
- yield full_line
- def _begin_mod_line(self, mod_name: str) -> str:
- return f"# BEGIN: {mod_name} modification by {self.script_name}"
- def _end_mod_line(self, mod_name: str) -> str:
- return f"# END: {mod_name} modification by {self.script_name}"
- def _on_snappy_detect_line(self, line: LineComponents) -> Iterable[str]:
- yield self._begin_mod_line("snappy_detect_line") + line.eol
- yield line.indent + "# " + line.line + line.eol
- yield line.indent + """set(HAVE_SNAPPY ON CACHE BOOL "")""" + line.eol
- yield self._end_mod_line("snappy_detect_line") + line.eol
- def _on_leveldb_include_start(self) -> Iterable[str]:
- line1 = self._split_line(self.lines[self.i])
- line2 = self._split_line(self.lines[self.i + 1])
- begin_mod_line = self._begin_mod_line("leveldb_include_start")
- if line1.line == begin_mod_line:
- return
- yield begin_mod_line + line1.eol
- yield line1.indent + "PRIVATE" + line1.eol
- yield line2.indent + self.snappy_source_dir_str + line2.eol
- yield line2.indent + self.snappy_binary_dir_str + line2.eol
- yield self._end_mod_line("leveldb_include_start") + line1.eol
- def _on_leveldb_snappy_link_line(self, line: LineComponents) -> Iterable[str]:
- yield self._begin_mod_line("leveldb_snappy_link_line") + line.eol
- yield line.indent + "# " + line.line + line.eol
- yield line.indent + f"target_link_libraries(leveldb Snappy::Snappy)" + line.eol
- yield self._end_mod_line("leveldb_snappy_link_line") + line.eol
- def _split_line(self, line: str) -> LineComponents:
- line_rstripped = line.rstrip()
- eol = line[len(line_rstripped):]
- line_stripped = line_rstripped.strip()
- indent = line_rstripped[:len(line_rstripped) - len(line_stripped)]
- return LineComponents(full=line, indent=indent, line=line_stripped, eol=eol)
- class LeveDbPatchException(Exception):
- pass
- if __name__ == "__main__":
- main()
|