#!/usr/bin/env fuchsia-vendored-python
#
# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""
Usage: gn_to_cmake.py <json_file_name>

gn gen out/config --ide=json --json-ide-script=../../gn/gn_to_cmake.py

or

gn gen out/config --ide=json
python gn/gn_to_cmake.py out/config/project.json

The first is recommended, as it will auto-update.
"""


import functools
import json
import os
import posixpath
import string
import sys


def CMakeStringEscape(a):
    """Escapes the string 'a' for use inside a CMake string.

    This means escaping
    '\' otherwise it may be seen as modifying the next character
    '"' otherwise it will end the string
    ';' otherwise the string becomes a list

    The following do not need to be escaped
    '#' when the lexer is in string state, this does not start a comment
    """
    return a.replace("\\", "\\\\").replace(";", "\\;").replace('"', '\\"')


def CMakeTargetEscape(a):
    """Escapes the string 'a' for use as a CMake target name.

    CMP0037 in CMake 3.0 restricts target names to "^[A-Za-z0-9_.:+-]+$"
    The ':' is only allowed for imported targets.
    """

    def Escape(c):
        if c in string.ascii_letters or c in string.digits or c in "_.+-":
            return c
        else:
            return "__"

    return "".join(map(Escape, a))


def SetVariable(out, variable_name, value):
    """Sets a CMake variable."""
    out.write('set("')
    out.write(CMakeStringEscape(variable_name))
    out.write('" "')
    out.write(CMakeStringEscape(value))
    out.write('")\n')


def SetVariableList(out, variable_name, values):
    """Sets a CMake variable to a list."""
    if not values:
        return SetVariable(out, variable_name, "")
    if len(values) == 1:
        return SetVariable(out, variable_name, values[0])
    out.write('list(APPEND "')
    out.write(CMakeStringEscape(variable_name))
    out.write('"\n  "')
    out.write('"\n  "'.join([CMakeStringEscape(value) for value in values]))
    out.write('")\n')


def SetFilesProperty(output, variable, property_name, values, sep):
    """Given a set of source files, sets the given property on them."""
    output.write("set_source_files_properties(")
    WriteVariable(output, variable)
    output.write(" PROPERTIES ")
    output.write(property_name)
    output.write(' "')
    for value in values:
        output.write(CMakeStringEscape(value))
        output.write(sep)
    output.write('")\n')


def SetCurrentTargetProperty(out, property_name, values, sep=""):
    """Given a target, sets the given property."""
    out.write('set_target_properties("${target}" PROPERTIES ')
    out.write(property_name)
    out.write(' "')
    for value in values:
        out.write(CMakeStringEscape(value))
        out.write(sep)
    out.write('")\n')


def WriteVariable(output, variable_name, prepend=None):
    if prepend:
        output.write(prepend)
    output.write("${")
    output.write(variable_name)
    output.write("}")


# See GetSourceFileType in gn
source_file_types = {
    ".cc": "cxx",
    ".cpp": "cxx",
    ".cxx": "cxx",
    ".c": "c",
    ".s": "asm",
    ".S": "asm",
    ".asm": "asm",
    ".o": "obj",
    ".obj": "obj",
}


class CMakeTargetType(object):
    def __init__(self, command, modifier, property_modifier, is_linkable):
        self.command = command
        self.modifier = modifier
        self.property_modifier = property_modifier
        self.is_linkable = is_linkable


CMakeTargetType.custom = CMakeTargetType(
    "add_custom_target", "SOURCES", None, False
)

# See GetStringForOutputType in gn
cmake_target_types = {
    "unknown": CMakeTargetType.custom,
    "group": CMakeTargetType.custom,
    "executable": CMakeTargetType("add_executable", None, "RUNTIME", True),
    "loadable_module": CMakeTargetType(
        "add_library", "MODULE", "LIBRARY", True
    ),
    "shared_library": CMakeTargetType("add_library", "SHARED", "LIBRARY", True),
    "static_library": CMakeTargetType(
        "add_library", "STATIC", "ARCHIVE", False
    ),
    "source_set": CMakeTargetType("add_library", "OBJECT", None, False),
    "copy": CMakeTargetType.custom,
    "action": CMakeTargetType.custom,
    "action_foreach": CMakeTargetType.custom,
    "bundle_data": CMakeTargetType.custom,
    "create_bundle": CMakeTargetType.custom,
}


def FindFirstOf(s, a):
    return min(s.find(i) for i in a if i in s)


class Project(object):
    def __init__(self, project_json):
        self.targets = project_json["targets"]
        build_settings = project_json["build_settings"]
        self.root_path = build_settings["root_path"]
        self.build_path = posixpath.join(
            self.root_path, build_settings["build_dir"][2:]
        )

    def GetAbsolutePath(self, path):
        if path.startswith("//"):
            return self.root_path + "/" + path[2:]
        else:
            return path

    def GetObjectSourceDependencies(self, gn_target_name, object_dependencies):
        """All OBJECT libraries whose sources have not been absorbed."""
        dependencies = self.targets[gn_target_name].get("deps", [])
        for dependency in dependencies:
            dependency_type = self.targets[dependency].get("type", None)
            if dependency_type == "source_set":
                object_dependencies.add(dependency)
            if dependency_type not in gn_target_types_that_absorb_objects:
                self.GetObjectSourceDependencies(
                    dependency, object_dependencies
                )

    def GetObjectLibraryDependencies(self, gn_target_name, object_dependencies):
        """All OBJECT libraries whose libraries have not been absorbed."""
        dependencies = self.targets[gn_target_name].get("deps", [])
        for dependency in dependencies:
            dependency_type = self.targets[dependency].get("type", None)
            if dependency_type == "source_set":
                object_dependencies.add(dependency)
                self.GetObjectLibraryDependencies(
                    dependency, object_dependencies
                )

    def GetCMakeTargetName(self, gn_target_name):
        # See <chromium>/src/tools/gn/label.cc#Resolve
        # //base/test:test_support(//build/toolchain/win:msvc)
        path_separator = FindFirstOf(gn_target_name, (":", "("))
        location = None
        name = None
        toolchain = None
        if not path_separator:
            location = gn_target_name[2:]
        else:
            location = gn_target_name[2:path_separator]
            toolchain_separator = gn_target_name.find("(", path_separator)
            if toolchain_separator == -1:
                name = gn_target_name[path_separator + 1 :]
            else:
                if toolchain_separator > path_separator:
                    name = gn_target_name[
                        path_separator + 1 : toolchain_separator
                    ]
                assert gn_target_name.endswith(")")
                toolchain = gn_target_name[toolchain_separator + 1 : -1]
        assert location or name

        cmake_target_name = None
        if location.endswith("/" + name):
            cmake_target_name = location
        elif location:
            cmake_target_name = location + "_" + name
        else:
            cmake_target_name = name
        if toolchain:
            cmake_target_name += "--" + toolchain
        return CMakeTargetEscape(cmake_target_name)


class Target(object):
    def __init__(self, gn_target_name, project):
        self.gn_name = gn_target_name
        self.properties = project.targets[self.gn_name]
        self.cmake_name = project.GetCMakeTargetName(self.gn_name)
        self.gn_type = self.properties.get("type", None)
        self.cmake_type = cmake_target_types.get(self.gn_type, None)


def WriteAction(out, target, project, sources, synthetic_dependencies):
    outputs = []
    output_directories = set()
    for output in target.properties.get("outputs", []):
        output_abs_path = project.GetAbsolutePath(output)
        outputs.append(output_abs_path)
        output_directory = posixpath.dirname(output_abs_path)
        if output_directory:
            output_directories.add(output_directory)
    outputs_name = "${target}__output"
    SetVariableList(out, outputs_name, outputs)

    out.write("add_custom_command(OUTPUT ")
    WriteVariable(out, outputs_name)
    out.write("\n")

    if output_directories:
        out.write('  COMMAND ${CMAKE_COMMAND} -E make_directory "')
        out.write('" "'.join(map(CMakeStringEscape, output_directories)))
        out.write('"\n')

    script = target.properties["script"]
    arguments = target.properties["args"]
    out.write('  COMMAND python "')
    out.write(CMakeStringEscape(project.GetAbsolutePath(script)))
    out.write('"')
    if arguments:
        out.write('\n    "')
        out.write('"\n    "'.join(map(CMakeStringEscape, arguments)))
        out.write('"')
    out.write("\n")

    out.write("  DEPENDS ")
    for sources_type_name in sources.values():
        WriteVariable(out, sources_type_name, " ")
    out.write("\n")

    # TODO: CMake 3.7 is introducing DEPFILE

    out.write('  WORKING_DIRECTORY "')
    out.write(CMakeStringEscape(project.build_path))
    out.write('"\n')

    out.write('  COMMENT "Action: ${target}"\n')

    out.write("  VERBATIM)\n")

    synthetic_dependencies.add(outputs_name)


def ExpandPlaceholders(source, a):
    source_dir, source_file_part = posixpath.split(source)
    source_name_part, _ = posixpath.splitext(source_file_part)
    # TODO: {{source_gen_dir}}, {{source_out_dir}}, {{response_file_name}}
    return (
        a.replace("{{source}}", source)
        .replace("{{source_file_part}}", source_file_part)
        .replace("{{source_name_part}}", source_name_part)
        .replace("{{source_dir}}", source_dir)
        .replace("{{source_root_relative_dir}}", source_dir)
    )


def WriteActionForEach(out, target, project, sources, synthetic_dependencies):
    all_outputs = target.properties.get("outputs", [])
    inputs = target.properties.get("sources", [])
    # TODO: consider expanding 'output_patterns' instead.
    outputs_per_input = len(all_outputs) / len(inputs)
    for count, source in enumerate(inputs):
        source_abs_path = project.GetAbsolutePath(source)

        outputs = []
        output_directories = set()
        for output in all_outputs[
            outputs_per_input * count : outputs_per_input * (count + 1)
        ]:
            output_abs_path = project.GetAbsolutePath(output)
            outputs.append(output_abs_path)
            output_directory = posixpath.dirname(output_abs_path)
            if output_directory:
                output_directories.add(output_directory)
        outputs_name = "${target}__output_" + str(count)
        SetVariableList(out, outputs_name, outputs)

        out.write("add_custom_command(OUTPUT ")
        WriteVariable(out, outputs_name)
        out.write("\n")

        if output_directories:
            out.write('  COMMAND ${CMAKE_COMMAND} -E make_directory "')
            out.write('" "'.join(map(CMakeStringEscape, output_directories)))
            out.write('"\n')

        script = target.properties["script"]
        # TODO: need to expand {{xxx}} in arguments
        arguments = target.properties["args"]
        out.write('  COMMAND python "')
        out.write(CMakeStringEscape(project.GetAbsolutePath(script)))
        out.write('"')
        if arguments:
            out.write('\n    "')
            expand = functools.partial(ExpandPlaceholders, source_abs_path)
            out.write(
                '"\n    "'.join(map(CMakeStringEscape, map(expand, arguments)))
            )
            out.write('"')
        out.write("\n")

        out.write("  DEPENDS")
        if "input" in sources:
            WriteVariable(out, sources["input"], " ")
        out.write(' "')
        out.write(CMakeStringEscape(source_abs_path))
        out.write('"\n')

        # TODO: CMake 3.7 is introducing DEPFILE

        out.write('  WORKING_DIRECTORY "')
        out.write(CMakeStringEscape(project.build_path))
        out.write('"\n')

        out.write('  COMMENT "Action ${target} on ')
        out.write(CMakeStringEscape(source_abs_path))
        out.write('"\n')

        out.write("  VERBATIM)\n")

        synthetic_dependencies.add(outputs_name)


def WriteCopy(out, target, project, sources, synthetic_dependencies):
    inputs = target.properties.get("sources", [])
    raw_outputs = target.properties.get("outputs", [])

    # TODO: consider expanding 'output_patterns' instead.
    outputs = []
    for output in raw_outputs:
        output_abs_path = project.GetAbsolutePath(output)
        outputs.append(output_abs_path)
    outputs_name = "${target}__output"
    SetVariableList(out, outputs_name, outputs)

    out.write("add_custom_command(OUTPUT ")
    WriteVariable(out, outputs_name)
    out.write("\n")

    for src, dst in zip(inputs, outputs):
        out.write('  COMMAND ${CMAKE_COMMAND} -E copy "')
        out.write(CMakeStringEscape(project.GetAbsolutePath(src)))
        out.write('" "')
        out.write(CMakeStringEscape(dst))
        out.write('"\n')

    out.write("  DEPENDS ")
    for sources_type_name in sources.values():
        WriteVariable(out, sources_type_name, " ")
    out.write("\n")

    out.write('  WORKING_DIRECTORY "')
    out.write(CMakeStringEscape(project.build_path))
    out.write('"\n')

    out.write('  COMMENT "Copy ${target}"\n')

    out.write("  VERBATIM)\n")

    synthetic_dependencies.add(outputs_name)


def WriteCompilerFlags(out, target, project, sources):
    # Hack, set linker language to c if no c or cxx files present.
    if not "c" in sources and not "cxx" in sources:
        SetCurrentTargetProperty(out, "LINKER_LANGUAGE", ["C"])

    # Mark uncompiled sources as uncompiled.
    if "input" in sources:
        SetFilesProperty(
            out, sources["input"], "HEADER_FILE_ONLY", ("True",), ""
        )
    if "other" in sources:
        SetFilesProperty(
            out, sources["other"], "HEADER_FILE_ONLY", ("True",), ""
        )

    # Mark object sources as linkable.
    if "obj" in sources:
        SetFilesProperty(out, sources["obj"], "EXTERNAL_OBJECT", ("True",), "")

    # TODO: 'output_name', 'output_dir', 'output_extension'
    # This includes using 'source_outputs' to direct compiler output.

    # Includes
    includes = target.properties.get("include_dirs", [])
    if includes:
        out.write('set_property(TARGET "${target}" ')
        out.write("APPEND PROPERTY INCLUDE_DIRECTORIES")
        for include_dir in includes:
            out.write('\n  "')
            out.write(project.GetAbsolutePath(include_dir))
            out.write('"')
        out.write(")\n")

    # Defines
    defines = target.properties.get("defines", [])
    if defines:
        SetCurrentTargetProperty(out, "COMPILE_DEFINITIONS", defines, ";")

    # Compile flags
    # "arflags", "asmflags", "cflags",
    # "cflags_c", "clfags_cc", "cflags_objc", "clfags_objcc"
    # CMake does not have per target lang compile flags.
    # TODO: $<$<COMPILE_LANGUAGE:CXX>:cflags_cc style generator expression.
    #       http://public.kitware.com/Bug/view.php?id=14857
    flags = []
    flags.extend(target.properties.get("cflags", []))
    cflags_asm = target.properties.get("asmflags", [])
    cflags_c = target.properties.get("cflags_c", [])
    cflags_cxx = target.properties.get("cflags_cc", [])
    if "c" in sources and not any(k in sources for k in ("asm", "cxx")):
        flags.extend(cflags_c)
    elif "cxx" in sources and not any(k in sources for k in ("asm", "c")):
        flags.extend(cflags_cxx)
    else:
        # TODO: This is broken, one cannot generally set properties on files,
        # as other targets may require different properties on the same files.
        if "asm" in sources and cflags_asm:
            SetFilesProperty(
                out, sources["asm"], "COMPILE_FLAGS", cflags_asm, " "
            )
        if "c" in sources and cflags_c:
            SetFilesProperty(out, sources["c"], "COMPILE_FLAGS", cflags_c, " ")
        if "cxx" in sources and cflags_cxx:
            SetFilesProperty(
                out, sources["cxx"], "COMPILE_FLAGS", cflags_cxx, " "
            )
    if flags:
        SetCurrentTargetProperty(out, "COMPILE_FLAGS", flags, " ")

    # Linker flags
    ldflags = target.properties.get("ldflags", [])
    if ldflags:
        SetCurrentTargetProperty(out, "LINK_FLAGS", ldflags, " ")


gn_target_types_that_absorb_objects = (
    "executable",
    "loadable_module",
    "shared_library",
    "static_library",
)


def WriteSourceVariables(out, target, project):
    # gn separates the sheep from the goats based on file extensions.
    # A full separation is done here because of flag handing (see Compile flags).
    source_types = {
        "cxx": [],
        "c": [],
        "asm": [],
        "obj": [],
        "obj_target": [],
        "input": [],
        "other": [],
    }

    all_sources = target.properties.get("sources", [])

    # As of cmake 3.11 add_library must have sources. If there are
    # no sources, add empty.cpp as the file to compile.
    if len(all_sources) == 0:
        all_sources.append(posixpath.join(project.build_path, "empty.cpp"))

    # TODO .def files on Windows
    for source in all_sources:
        _, ext = posixpath.splitext(source)
        source_abs_path = project.GetAbsolutePath(source)
        source_types[source_file_types.get(ext, "other")].append(
            source_abs_path
        )

    for input_path in target.properties.get("inputs", []):
        input_abs_path = project.GetAbsolutePath(input_path)
        source_types["input"].append(input_abs_path)

    # OBJECT library dependencies need to be listed as sources.
    # Only executables and non-OBJECT libraries may reference an OBJECT library.
    # https://gitlab.kitware.com/cmake/cmake/issues/14778
    if target.gn_type in gn_target_types_that_absorb_objects:
        object_dependencies = set()
        project.GetObjectSourceDependencies(target.gn_name, object_dependencies)
        for dependency in object_dependencies:
            cmake_dependency_name = project.GetCMakeTargetName(dependency)
            obj_target_sources = (
                "$<TARGET_OBJECTS:" + cmake_dependency_name + ">"
            )
            source_types["obj_target"].append(obj_target_sources)

    sources = {}
    for source_type, sources_of_type in source_types.items():
        if sources_of_type:
            sources[source_type] = "${target}__" + source_type + "_srcs"
            SetVariableList(out, sources[source_type], sources_of_type)
    return sources


def WriteTarget(out, target, project):
    out.write("\n#")
    out.write(target.gn_name)
    out.write("\n")

    if target.cmake_type is None:
        print(
            "Target %s has unknown target type %s, skipping."
            % (target.gn_name, target.gn_type)
        )
        return

    SetVariable(out, "target", target.cmake_name)

    sources = WriteSourceVariables(out, target, project)

    synthetic_dependencies = set()
    if target.gn_type == "action":
        WriteAction(out, target, project, sources, synthetic_dependencies)
    if target.gn_type == "action_foreach":
        WriteActionForEach(
            out, target, project, sources, synthetic_dependencies
        )
    if target.gn_type == "copy":
        WriteCopy(out, target, project, sources, synthetic_dependencies)

    out.write(target.cmake_type.command)
    out.write('("${target}"')
    if target.cmake_type.modifier is not None:
        out.write(" ")
        out.write(target.cmake_type.modifier)
    for sources_type_name in sources.values():
        WriteVariable(out, sources_type_name, " ")
    if synthetic_dependencies:
        out.write(" DEPENDS")
        for synthetic_dependencie in synthetic_dependencies:
            WriteVariable(out, synthetic_dependencie, " ")
    out.write(")\n")

    if target.cmake_type.command != "add_custom_target":
        WriteCompilerFlags(out, target, project, sources)

    libraries = set()
    nonlibraries = set()

    dependencies = set(target.properties.get("deps", []))
    # Transitive OBJECT libraries are in sources.
    # Those sources are dependent on the OBJECT library dependencies.
    # Those sources cannot bring in library dependencies.
    object_dependencies = set()
    if target.gn_type != "source_set":
        project.GetObjectLibraryDependencies(
            target.gn_name, object_dependencies
        )
    for object_dependency in object_dependencies:
        dependencies.update(
            project.targets.get(object_dependency).get("deps", [])
        )

    for dependency in dependencies:
        gn_dependency_type = project.targets.get(dependency, {}).get(
            "type", None
        )
        cmake_dependency_type = cmake_target_types.get(gn_dependency_type, None)
        cmake_dependency_name = project.GetCMakeTargetName(dependency)
        if cmake_dependency_type.command != "add_library":
            nonlibraries.add(cmake_dependency_name)
        elif cmake_dependency_type.modifier != "OBJECT":
            if target.cmake_type.is_linkable:
                libraries.add(cmake_dependency_name)
            else:
                nonlibraries.add(cmake_dependency_name)

    # Non-library dependencies.
    if nonlibraries:
        out.write('add_dependencies("${target}"')
        for nonlibrary in nonlibraries:
            out.write('\n  "')
            out.write(nonlibrary)
            out.write('"')
        out.write(")\n")

    # Non-OBJECT library dependencies.
    external_libraries = target.properties.get("libs", [])
    if target.cmake_type.is_linkable and (external_libraries or libraries):
        library_dirs = target.properties.get("lib_dirs", [])
        if library_dirs:
            SetVariableList(out, "${target}__library_directories", library_dirs)

        system_libraries = []
        for external_library in external_libraries:
            if "/" in external_library:
                libraries.add(project.GetAbsolutePath(external_library))
            else:
                if external_library.endswith(".framework"):
                    external_library = external_library[: -len(".framework")]
                system_library = "library__" + external_library
                if library_dirs:
                    system_library = system_library + "__for_${target}"
                out.write('find_library("')
                out.write(CMakeStringEscape(system_library))
                out.write('" "')
                out.write(CMakeStringEscape(external_library))
                out.write('"')
                if library_dirs:
                    out.write(' PATHS "')
                    WriteVariable(out, "${target}__library_directories")
                    out.write('"')
                out.write(")\n")
                system_libraries.append(system_library)
        out.write('target_link_libraries("${target}"')
        for library in libraries:
            out.write('\n  "')
            out.write(CMakeStringEscape(library))
            out.write('"')
        for system_library in system_libraries:
            WriteVariable(out, system_library, '\n  "')
            out.write('"')
        out.write(")\n")


def WriteProject(project):
    out = open(posixpath.join(project.build_path, "CMakeLists.txt"), "w+")
    extName = posixpath.join(project.build_path, "CMakeLists.ext")
    out.write("# Generated by %s.\n" % os.path.basename(__file__))
    out.write("cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)\n")
    out.write("cmake_policy(VERSION 2.8.8)\n\n")

    out.write('file(WRITE "')
    out.write(
        CMakeStringEscape(posixpath.join(project.build_path, "empty.cpp"))
    )
    out.write('")\n')

    # Update the gn generated ninja build.
    # If a build file has changed, this will update CMakeLists.ext if
    # gn gen out/config --ide=json --json-ide-script=../../gn/gn_to_cmake.py
    # style was used to create this config.
    out.write("execute_process(COMMAND\n")
    out.write('  ninja -C "')
    out.write(CMakeStringEscape(project.build_path))
    out.write('" build.ninja\n')
    out.write("  RESULT_VARIABLE ninja_result)\n")
    out.write("if (ninja_result)\n")
    out.write("  message(WARNING ")
    out.write('"Regeneration failed running ninja: ${ninja_result}")\n')
    out.write("endif()\n")

    out.write('include("')
    out.write(CMakeStringEscape(extName))
    out.write('")\n')
    out.close()

    out = open(extName, "w+")
    out.write("# Generated by %s.\n", os.path.basename(__file__))
    out.write("cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)\n")
    out.write("cmake_policy(VERSION 2.8.8)\n")

    # The following appears to be as-yet undocumented.
    # http://public.kitware.com/Bug/view.php?id=8392
    out.write("enable_language(ASM)\n\n")
    # ASM-ATT does not support .S files.
    # output.write('enable_language(ASM-ATT)\n')

    # Current issues with automatic re-generation:
    # The gn generated build.ninja target uses build.ninja.d
    #   but build.ninja.d does not contain the ide or gn.
    # Currently the ide is not run if the project.json file is not changed
    #   but the ide needs to be run anyway if it has itself changed.
    #   This can be worked around by deleting the project.json file.
    out.write('file(READ "')
    gn_deps_file = posixpath.join(project.build_path, "build.ninja.d")
    out.write(CMakeStringEscape(gn_deps_file))
    out.write('" "gn_deps_string" OFFSET ')
    out.write(str(len("build.ninja: ")))
    out.write(")\n")
    # One would think this would need to worry about escaped spaces
    # but gn doesn't escape spaces here (it generates invalid .d files).
    out.write('string(REPLACE " " ";" "gn_deps" ${gn_deps_string})\n')
    out.write('foreach("gn_dep" ${gn_deps})\n')
    out.write('  configure_file("')
    out.write(CMakeStringEscape(project.build_path))
    out.write('${gn_dep}" "CMakeLists.devnull" COPYONLY)\n')
    out.write('endforeach("gn_dep")\n')

    out.write('list(APPEND other_deps "')
    out.write(CMakeStringEscape(os.path.abspath(__file__)))
    out.write('")\n')
    out.write('foreach("other_dep" ${other_deps})\n')
    out.write(
        '  configure_file("${other_dep}" "CMakeLists.devnull" COPYONLY)\n'
    )
    out.write('endforeach("other_dep")\n')

    for target_name in project.targets.keys():
        out.write("\n")
        WriteTarget(out, Target(target_name, project), project)


def main():
    if len(sys.argv) != 2:
        print("Usage: " + sys.argv[0] + " <json_file_name>")
        exit(1)

    json_path = sys.argv[1]
    project = None
    with open(json_path, "r") as json_file:
        project = json.loads(json_file.read())

    WriteProject(Project(project))


if __name__ == "__main__":
    main()
