args_parser.add_argument(
"--out-dep-file",
type=str,
required=False,
help="Location of output depfile. Optional when used with gcc. "
+ "If not given, will not output dep file",
)
args_parser.add_argument(
"--in-src-file",
type=str,
required=True,
help="Location of source file to process",
)
args_parser.add_argument(
"--cxx-compiler", type=str, required=True, help="C++ compiler to use"
)
args_parser.add_argument(
"--include-dirs", type=str, help="Include directories separated by semicolon"
)
args_parser.add_argument(
"--additional-raw-arguments",
type=str,
help="Additional arguments to pass to the compiler. "
+ "Only for use on UNIX systems",
)
args_parser.add_argument(
"--macro-defs",
type=str,
help="Macro definitions in the form VALA=CONTENTA or VALB",
)
args_parser.add_argument(
"--dep-file-only",
action="store_true",
help="If given, will only generate dependency file without preprocessed file."
+ "For gcc usage only.",
)
return args_parser.parse_args()
class CompileOptions:
def __init__(
self,
compiler: str,
include_dirs: Optional[List[str]] = None,
macros: Optional[List[str]] = None,
**kwargs,
):
"""
:param compiler: C++ compiler to use for preprocessing
:param include_dirs: List of include directories to pass to C++ compiler for
preprocessing
:param macros: List of macros to pass to the C++ compiler for preprocessing.
Must be in 'MACRO' or 'MACRO=VALUE' form.
:param kwargs: Accepts two extra arguments:
- "extra_flags": Extra flags to pass to compiler for preprocessing
- "standard": C++ standard to use.
This is passed to the compiler as "-std=c++<standard>".
"""
self._compiler = compiler
self._include_dirs = include_dirs or []
self._macros = macros or []
self._extra_flags: List[str] = kwargs.get("extra_flags") or []
self._standard: str = kwargs.get("standard") or "17"
def escape_windows_path(raw_path: str) -> str:
escape_chars = {" ", "$", "#"}
with io.StringIO() as ret_str_io:
for char in raw_path:
if char in escape_chars:
ret_str_io.write("\\")
ret_str_io.write(char)
return ret_str_io.getvalue()
include_fil_str = " ".join(
escape_windows_path(include_fil)
for include_fil in dep_data["Data"].get("Includes", [])
)
with open(depfile_out, "w", encoding="utf-8") as depfile_writer:
depfile_writer.write(escape_windows_path(preproc_out))
depfile_writer.write(": ")
depfile_writer.write(include_fil_str)
def main():
args = parse_args()
opt = CompileOptions(
args.cxx_compiler,
args.include_dirs.split(";") if args.include_dirs else None,
args.macro_defs.split(";") if args.macro_defs else None,
extra_flags=(
shlex.split(args.additional_raw_arguments)
if args.additional_raw_arguments
else None
),
standard=args.cxx_standard,
)
if args.msvc:
compile_for_preproc_and_depfile_msvc(
opt, args.in_src_file, args.out_i_file, args.out_dep_file
)
else:
if not args.out_dep_file and args.dep_file_only:
raise RuntimeError("Dependency file output must be given")
if args.out_dep_file:
compile_for_depfile_gcc(
opt, args.in_src_file, args.out_i_file, args.out_dep_file
)
if not args.dep_file_only:
compile_for_preproc_gcc(opt, args.in_src_file, args.out_i_file)