1b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarfrom __future__ import absolute_import
2ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbarimport os
31cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbarimport sys
4ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
5b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarimport llvmbuild.componentinfo as componentinfo
6b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarimport llvmbuild.configutil as configutil
7df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesfrom llvmbuild.util import fatal, note
91cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
101cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar###
111cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1257574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbardef cmake_quote_string(value):
1357574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    """
1457574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    cmake_quote_string(value) -> str
1557574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
1657574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    Return a quoted form of the given value that is suitable for use in CMake
1757574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    language files.
1857574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    """
1957574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
2057574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    # Currently, we only handle escaping backslashes.
2157574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    value = value.replace("\\", "\\\\")
2257574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
2357574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    return value
2457574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
25d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbardef cmake_quote_path(value):
26d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    """
27d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    cmake_quote_path(value) -> str
28d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
29d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    Return a quoted form of the given value that is suitable for use in CMake
30d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    language files.
31d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    """
32d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
33d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # CMake has a bug in it's Makefile generator that doesn't properly quote
34d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # strings it generates. So instead of using proper quoting, we just use "/"
35d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # style paths.  Currently, we only handle escaping backslashes.
36d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    value = value.replace("\\", "/")
37d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
38d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    return value
39d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
4020fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbardef mk_quote_string_for_target(value):
4120fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    """
4220fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    mk_quote_string_for_target(target_name) -> str
4320fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
4420fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    Return a quoted form of the given target_name suitable for including in a
4520fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    Makefile as a target name.
4620fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    """
4720fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
4820fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    # The only quoting we currently perform is for ':', to support msys users.
4920fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    return value.replace(":", "\\:")
5020fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
51195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbardef make_install_dir(path):
52195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    """
53195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    make_install_dir(path) -> None
54195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
55195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    Create the given directory path for installation, including any parents.
56195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    """
57195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
58d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    # os.makedirs considers it an error to be called with an existent path.
59195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    if not os.path.exists(path):
60195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        os.makedirs(path)
61195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
6220fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar###
6320fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
64df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbarclass LLVMProjectInfo(object):
65df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    @staticmethod
66df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def load_infos_from_path(llvmbuild_source_root):
67e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar        def recurse(subpath):
68e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Load the LLVMBuild file.
69e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            llvmbuild_path = os.path.join(llvmbuild_source_root + subpath,
70e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                                          'LLVMBuild.txt')
71e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            if not os.path.exists(llvmbuild_path):
72e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                fatal("missing LLVMBuild.txt file at: %r" % (llvmbuild_path,))
73e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
74e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Parse the components from it.
75e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            common,info_iter = componentinfo.load_from_path(llvmbuild_path,
76e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                                                            subpath)
77e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            for info in info_iter:
78df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar                yield info
79df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
80e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Recurse into the specified subdirectories.
81e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            for subdir in common.get_list("subdirectories"):
82e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                for item in recurse(os.path.join(subpath, subdir)):
83e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                    yield item
84e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
85e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar        return recurse("/")
86e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
87df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    @staticmethod
88df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def load_from_path(source_root, llvmbuild_source_root):
89df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        infos = list(
90df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar            LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root))
91df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
92df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        return LLVMProjectInfo(source_root, infos)
93df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
94df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def __init__(self, source_root, component_infos):
951cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Store our simple ivars.
96df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        self.source_root = source_root
97b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.component_infos = list(component_infos)
98b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.component_info_map = None
99b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.ordered_component_infos = None
100b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
101b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    def validate_components(self):
102b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        """validate_components() -> None
103b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
104b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        Validate that the project components are well-defined. Among other
105b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        things, this checks that:
106b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar          - Components have valid references.
107b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar          - Components references do not form cycles.
108b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
109b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        We also construct the map from component names to info, and the
110b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        topological ordering of components.
111b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        """
112df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
1131cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Create the component info map and validate that component names are
1141cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # unique.
1151cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        self.component_info_map = {}
116b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        for ci in self.component_infos:
1171cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            existing = self.component_info_map.get(ci.name)
1181cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if existing is not None:
1191cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # We found a duplicate component name, report it and error out.
1201cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                fatal("found duplicate component %r (at %r and %r)" % (
1211cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                        ci.name, ci.subpath, existing.subpath))
1221cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            self.component_info_map[ci.name] = ci
1231cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
124efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Disallow 'all' as a component name, which is a special case.
125efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        if 'all' in self.component_info_map:
126efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            fatal("project is not allowed to define 'all' component")
127efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
12800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        # Add the root component.
12986c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        if '$ROOT' in self.component_info_map:
13086c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            fatal("project is not allowed to define $ROOT component")
13186c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        self.component_info_map['$ROOT'] = componentinfo.GroupComponentInfo(
13286c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            '/', '$ROOT', None)
13300b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        self.component_infos.append(self.component_info_map['$ROOT'])
13486c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1351cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Topologically order the component information according to their
1361cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # component references.
1371cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        def visit_component_info(ci, current_stack, current_set):
1381cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Check for a cycles.
1391cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if ci in current_set:
1401cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # We found a cycle, report it and error out.
1411cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                cycle_description = ' -> '.join(
1421cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    '%r (%s)' % (ci.name, relation)
1431cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    for relation,ci in current_stack)
1441cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                fatal("found cycle to %r after following: %s -> %s" % (
1451cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                        ci.name, cycle_description, ci.name))
1461cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1471cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # If we have already visited this item, we are done.
1481cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if ci not in components_to_visit:
1491cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                return
1501cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1511cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Otherwise, mark the component info as visited and traverse.
1521cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            components_to_visit.remove(ci)
1531cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
15486c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            # Validate the parent reference, which we treat specially.
15500b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            if ci.parent is not None:
15600b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                parent = self.component_info_map.get(ci.parent)
15700b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                if parent is None:
15800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                    fatal("component %r has invalid reference %r (via %r)" % (
15900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                            ci.name, ci.parent, 'parent'))
16000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                ci.set_parent_instance(parent)
16186c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1621cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            for relation,referent_name in ci.get_component_references():
1631cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # Validate that the reference is ok.
1641cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                referent = self.component_info_map.get(referent_name)
1651cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                if referent is None:
1661cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    fatal("component %r has invalid reference %r (via %r)" % (
1671cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                            ci.name, referent_name, relation))
1681cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1691cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # Visit the reference.
1701cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_stack.append((relation,ci))
1711cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_set.add(ci)
1721cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                visit_component_info(referent, current_stack, current_set)
1731cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_set.remove(ci)
1741cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_stack.pop()
1751cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1761cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Finally, add the component info to the ordered list.
1771cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            self.ordered_component_infos.append(ci)
1781cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
17986c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # FIXME: We aren't actually correctly checking for cycles along the
18086c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # parent edges. Haven't decided how I want to handle this -- I thought
18186c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # about only checking cycles by relation type. If we do that, it falls
18286c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # out easily. If we don't, we should special case the check.
18386c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1841cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        self.ordered_component_infos = []
185da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi        components_to_visit = sorted(
186da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi            set(self.component_infos),
187da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi            key = lambda c: c.name)
1881cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        while components_to_visit:
189b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            visit_component_info(components_to_visit[0], [], set())
1901cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
19100b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        # Canonicalize children lists.
19200b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        for c in self.ordered_component_infos:
19300b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            c.children.sort(key = lambda c: c.name)
19400b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
19500b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    def print_tree(self):
19600b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        def visit(node, depth = 0):
197b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            print('%s%-40s (%s)' % ('  '*depth, node.name, node.type_name))
19800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            for c in node.children:
19900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                visit(c, depth + 1)
20000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        visit(self.component_info_map['$ROOT'])
20100b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
20243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    def write_components(self, output_path):
20343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # Organize all the components by the directory their LLVMBuild file
20443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # should go in.
20543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        info_basedir = {}
20643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        for ci in self.component_infos:
20743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Ignore the $ROOT component.
20843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if ci.parent is None:
20943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                continue
21043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
21143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            info_basedir[ci.subpath] = info_basedir.get(ci.subpath, []) + [ci]
21243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
213b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        # Compute the list of subdirectories to scan.
214b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        subpath_subdirs = {}
215b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        for ci in self.component_infos:
216b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Ignore root components.
217b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            if ci.subpath == '/':
218b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                continue
219b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
220b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Otherwise, append this subpath to the parent list.
221b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            parent_path = os.path.dirname(ci.subpath)
222b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            subpath_subdirs[parent_path] = parent_list = subpath_subdirs.get(
223b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                parent_path, set())
224b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            parent_list.add(os.path.basename(ci.subpath))
225b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
22643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # Generate the build files.
22743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        for subpath, infos in info_basedir.items():
22843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Order the components by name to have a canonical ordering.
22943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            infos.sort(key = lambda ci: ci.name)
23043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
23143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Format the components into llvmbuild fragments.
232b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            fragments = []
233b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
234b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Add the common fragments.
235b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            subdirectories = subpath_subdirs.get(subpath)
236b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            if subdirectories:
237b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragment = """\
238b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbarsubdirectories = %s
239b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar""" % (" ".join(sorted(subdirectories)),)
240b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragments.append(("common", fragment))
241b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
242b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Add the component fragments.
243b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            num_common_fragments = len(fragments)
244b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            for ci in infos:
245b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragment = ci.get_llvmbuild_fragment()
246b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                if fragment is None:
247b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                    continue
248b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
249b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                name = "component_%d" % (len(fragments) - num_common_fragments)
250b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragments.append((name, fragment))
251b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
25243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if not fragments:
25343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                continue
25443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
25543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            assert subpath.startswith('/')
25643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            directory_path = os.path.join(output_path, subpath[1:])
25743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
25843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Create the directory if it does not already exist.
25943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if not os.path.exists(directory_path):
26043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                os.makedirs(directory_path)
26143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
262a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # In an effort to preserve comments (which aren't parsed), read in
263a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # the original file and extract the comments. We only know how to
264a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # associate comments that prefix a section name.
265a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            f = open(infos[0]._source_path)
266a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            comments_map = {}
267a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            comment_block = ""
268a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            for ln in f:
269a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                if ln.startswith(';'):
270a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    comment_block += ln
271a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                elif ln.startswith('[') and ln.endswith(']\n'):
272b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                    comments_map[ln[1:-2]] = comment_block
273a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                else:
274a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    comment_block = ""
275a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            f.close()
276a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar
277a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # Create the LLVMBuild fil[e.
27843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            file_path = os.path.join(directory_path, 'LLVMBuild.txt')
27943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            f = open(file_path, "w")
280fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar
281fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            # Write the header.
282fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_fmt = ';===- %s %s-*- Conf -*--===;'
283fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_name = '.' + os.path.join(subpath, 'LLVMBuild.txt')
284fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
285fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_string = header_fmt % (header_name, header_pad)
286b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
287fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar%s
288fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
289fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;                     The LLVM Compiler Infrastructure
290fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
291fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; This file is distributed under the University of Illinois Open Source
292fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; License. See LICENSE.TXT for details.
293fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
294fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;===------------------------------------------------------------------------===;
295fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
296fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; This is an LLVMBuild description file for the components in this subdirectory.
297fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
298fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; For more information on the LLVMBuild system, please see:
299fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
300fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;   http://llvm.org/docs/LLVMBuild.html
301fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
302fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;===------------------------------------------------------------------------===;
303b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
304b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
305fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar
306b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Write out each fragment.each component fragment.
307b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            for name,fragment in fragments:
308a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                comment = comments_map.get(name)
309a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                if comment is not None:
310a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    f.write(comment)
311b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                f.write("[%s]\n" % name)
31243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                f.write(fragment)
313b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                if fragment is not fragments[-1][1]:
314b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                    f.write('\n')
315b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
31643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            f.close()
31743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
318754935418133ece1f51d1857a61d538797c34891Preston Gurd    def write_library_table(self, output_path, enabled_optional_components):
319efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Write out the mapping from component names to required libraries.
320efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        #
321efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # We do this in topological order so that we know we can append the
322efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # dependencies for added library groups.
323efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        entries = {}
324efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        for c in self.ordered_component_infos:
325177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            # Skip optional components which are not enabled.
326754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name == 'OptionalLibrary' \
327754935418133ece1f51d1857a61d538797c34891Preston Gurd                and c.name not in enabled_optional_components:
328754935418133ece1f51d1857a61d538797c34891Preston Gurd                continue
329754935418133ece1f51d1857a61d538797c34891Preston Gurd
330177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            # Skip target groups which are not enabled.
331177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            tg = c.get_parent_target_group()
332177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            if tg and not tg.enabled:
333177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar                continue
334177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar
335c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar            # Only certain components are in the table.
336754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name not in ('Library', 'OptionalLibrary', \
337754935418133ece1f51d1857a61d538797c34891Preston Gurd                                   'LibraryGroup', 'TargetGroup'):
338efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                continue
339efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
340efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Compute the llvm-config "component name". For historical reasons,
341efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # this is lowercased based on the library name.
342efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            llvmconfig_component_name = c.get_llvmconfig_component_name()
343efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
344efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Get the library name, or None for LibraryGroups.
345754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name == 'Library' or c.type_name == 'OptionalLibrary':
346bb53bbb7d4b1ac3da416d922101d4cbc280b145cDaniel Dunbar                library_name = c.get_prefixed_library_name()
347b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                is_installed = c.installed
348c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar            else:
349c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar                library_name = None
350b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                is_installed = True
351efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
352efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Get the component names of all the required libraries.
353efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            required_llvmconfig_component_names = [
354efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                self.component_info_map[dep].get_llvmconfig_component_name()
355efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                for dep in c.required_libraries]
356efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
357efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Insert the entries for library groups we should add to.
358efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            for dep in c.add_to_library_groups:
359efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                entries[dep][2].append(llvmconfig_component_name)
360efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
361efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Add the entry.
362efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            entries[c.name] = (llvmconfig_component_name, library_name,
363b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                               required_llvmconfig_component_names,
364b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                               is_installed)
365efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
366efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Convert to a list of entries and sort by name.
367b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        entries = list(entries.values())
368efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
369efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Create an 'all' pseudo component. We keep the dependency list small by
370efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # only listing entries that have no other dependents.
371efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        root_entries = set(e[0] for e in entries)
372b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        for _,_,deps,_ in entries:
373efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            root_entries -= set(deps)
374b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        entries.append(('all', None, root_entries, True))
375efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
376efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        entries.sort()
377efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
378efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Compute the maximum number of required libraries, plus one so there is
379efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # always a sentinel.
380efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        max_required_libraries = max(len(deps)
381b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                                     for _,_,deps,_ in entries) + 1
382efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
383efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Write out the library table.
384195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
385efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        f = open(output_path, 'w')
386b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
387efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//===- llvm-build generated file --------------------------------*- C++ -*-===//
388efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
389efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar// Component Library Depenedency Table
390efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
391efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar// Automatically generated file, do not edit!
392efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
393efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//===----------------------------------------------------------------------===//
394b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
395b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
396b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('struct AvailableComponent {\n')
397b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// The name of the component.\n')
398b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *Name;\n')
399b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
400b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// The name of the library for this component (or NULL).\n')
401b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *Library;\n')
402b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
403b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// Whether the component is installed.\n')
404b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  bool IsInstalled;\n')
405b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
406b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\
407b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar  /// The list of libraries required when linking this component.\n')
408b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *RequiredLibraries[%d];\n' % (
409b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            max_required_libraries))
410b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('} AvailableComponents[%d] = {\n' % len(entries))
411b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        for name,library_name,required_names,is_installed in entries:
412efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            if library_name is None:
413efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                library_name_as_cstr = '0'
414efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            else:
415bb53bbb7d4b1ac3da416d922101d4cbc280b145cDaniel Dunbar                library_name_as_cstr = '"lib%s.a"' % library_name
416b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write('  { "%s", %s, %d, { %s } },\n' % (
417b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                name, library_name_as_cstr, is_installed,
418efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                ', '.join('"%s"' % dep
419b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                          for dep in required_names)))
420b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('};\n')
421efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        f.close()
422efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
4235086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar    def get_required_libraries_for_component(self, ci, traverse_groups = False):
4245086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        """
4255086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        get_required_libraries_for_component(component_info) -> iter
4265086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4275086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        Given a Library component info descriptor, return an iterator over all
4285086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        of the directly required libraries for linking with this component. If
4295086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        traverse_groups is True, then library and target groups will be
4305086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        traversed to include their required libraries.
4315086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        """
4325086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4335086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        assert ci.type_name in ('Library', 'LibraryGroup', 'TargetGroup')
4345086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4355086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        for name in ci.required_libraries:
4365086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # Get the dependency info.
4375086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            dep = self.component_info_map[name]
4385086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4395086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # If it is a library, yield it.
4405086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            if dep.type_name == 'Library':
4415086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                yield dep
4425086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                continue
4435086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4445086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # Otherwise if it is a group, yield or traverse depending on what
4455086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # was requested.
4465086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            if dep.type_name in ('LibraryGroup', 'TargetGroup'):
4475086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                if not traverse_groups:
4485086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    yield dep
4495086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    continue
4505086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4515086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                for res in self.get_required_libraries_for_component(dep, True):
4525086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    yield res
4535086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4541688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    def get_fragment_dependencies(self):
45502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        """
4561688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        get_fragment_dependencies() -> iter
45702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
4581688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Compute the list of files (as absolute paths) on which the output
4591688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        fragments depend (i.e., files for which a modification should trigger a
4601688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        rebuild of the fragment).
46102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        """
46202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
46302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Construct a list of all the dependencies of the Makefile fragment
46402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # itself. These include all the LLVMBuild files themselves, as well as
46502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # all of our own sources.
466309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        #
467309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        # Many components may come from the same file, so we make sure to unique
468309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        # these.
469309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        build_paths = set()
47002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for ci in self.component_infos:
471309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar            p = os.path.join(self.source_root, ci.subpath[1:], 'LLVMBuild.txt')
472309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar            if p not in build_paths:
473309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar                yield p
474309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar                build_paths.add(p)
47502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
47602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Gather the list of necessary sources by just finding all loaded
47702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # modules that are inside the LLVM source tree.
47802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for module in sys.modules.values():
47902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # Find the module path.
48002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if not hasattr(module, '__file__'):
48102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                continue
48202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            path = getattr(module, '__file__')
48302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if not path:
48402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                continue
48502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
48602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # Strip off any compiled suffix.
48702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
48802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                path = path[:-1]
48902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
49002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # If the path exists and is in the source tree, consider it a
49102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # dependency.
49202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if (path.startswith(self.source_root) and os.path.exists(path)):
4931688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar                yield path
4941688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
4951688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    def write_cmake_fragment(self, output_path):
4961688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
4971688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        write_cmake_fragment(output_path) -> None
4981688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
4991688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Generate a CMake fragment which includes all of the collated LLVMBuild
5001688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        information in a format that is easily digestible by a CMake. The exact
5011688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        contents of this are closely tied to how the CMake configuration
5021688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        integrates LLVMBuild, see CMakeLists.txt in the top-level.
5031688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
5041688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5051688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        dependencies = list(self.get_fragment_dependencies())
5061688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5071688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write out the CMake fragment.
508195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
5091688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        f = open(output_path, 'w')
5101688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5111688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write the header.
5121688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_fmt = '\
5131688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#'
5141688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_name = os.path.basename(output_path)
5151688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
5161688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_string = header_fmt % (header_name, header_pad)
517b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
5181688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar%s
5191688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5201688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#                     The LLVM Compiler Infrastructure
5211688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5221688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file is distributed under the University of Illinois Open Source
5231688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# License. See LICENSE.TXT for details.
5241688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5251688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===------------------------------------------------------------------------===#
5261688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5271688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file contains the LLVMBuild project information in a format easily
5281688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# consumed by the CMake based build system.
5291688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5301688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file is autogenerated by llvm-build, do not edit!
5311688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5321688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===------------------------------------------------------------------------===#
533b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
534b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
5351688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5361688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write the dependency information in the best way we can.
537b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""
5381688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# LLVMBuild CMake fragment dependencies.
5391688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5401688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# CMake has no builtin way to declare that the configuration depends on
5411688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# a particular file. However, a side effect of configure_file is to add
5421688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# said input file to CMake's internal dependency list. So, we use that
5431688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# and a dummy output file to communicate the dependency information to
5441688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# CMake.
5451688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5461688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# FIXME: File a CMake RFE to get a properly supported version of this
547b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# feature.
548b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
5491688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        for dep in dependencies:
550b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
5511688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbarconfigure_file(\"%s\"
552b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar               ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % (
553b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                cmake_quote_path(dep),))
55457574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
5555086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        # Write the properties we use to encode the required library dependency
5565086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        # information in a form CMake can easily use directly.
557b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""
5585086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar# Explicit library dependency information.
5595086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar#
5605086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar# The following property assignments effectively create a map from component
561b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# names to required libraries, in a way that is easily accessed from CMake.
562b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
5635086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        for ci in self.ordered_component_infos:
5645086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # We only write the information for libraries currently.
5655086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            if ci.type_name != 'Library':
5665086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                continue
5675086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
568b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
569b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarset_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
5705086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                ci.get_prefixed_library_name(), " ".join(sorted(
5715086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                     dep.get_prefixed_library_name()
572b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                     for dep in self.get_required_libraries_for_component(ci)))))
5735086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
5741688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        f.close()
5751688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    def write_cmake_exports_fragment(self, output_path):
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        """
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        write_cmake_exports_fragment(output_path) -> None
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Generate a CMake fragment which includes LLVMBuild library
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        dependencies expressed similarly to how CMake would write
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        them via install(EXPORT).
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        """
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        dependencies = list(self.get_fragment_dependencies())
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        # Write out the CMake exports fragment.
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        make_install_dir(os.path.dirname(output_path))
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f = open(output_path, 'w')
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f.write("""\
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# Explicit library dependency information.
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# The following property assignments tell CMake about link
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# dependencies of libraries imported from LLVM.
59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines""")
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for ci in self.ordered_component_infos:
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            # We only write the information for libraries currently.
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if ci.type_name != 'Library':
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                continue
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            # Skip disabled targets.
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            tg = ci.get_parent_target_group()
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if tg and not tg.enabled:
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                continue
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            f.write("""\
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesset_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                ci.get_prefixed_library_name(), " ".join(sorted(
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     dep.get_prefixed_library_name()
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     for dep in self.get_required_libraries_for_component(ci)))))
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f.close()
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6151688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    def write_make_fragment(self, output_path):
6161688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
6171688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        write_make_fragment(output_path) -> None
6181688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
6191688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Generate a Makefile fragment which includes all of the collated
6201688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        LLVMBuild information in a format that is easily digestible by a
6211688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Makefile. The exact contents of this are closely tied to how the LLVM
6221688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Makefiles integrate LLVMBuild, see Makefile.rules in the top-level.
6231688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
6241688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
6251688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        dependencies = list(self.get_fragment_dependencies())
62602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
62702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write out the Makefile fragment.
628195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
62902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        f = open(output_path, 'w')
63002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
63102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write the header.
63202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_fmt = '\
63302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===-- %s - LLVMBuild Configuration for LLVM %s-*- Makefile -*--===#'
63402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_name = os.path.basename(output_path)
63502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
63602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_string = header_fmt % (header_name, header_pad)
637b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
63802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar%s
63902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
64002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#                     The LLVM Compiler Infrastructure
64102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
64202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file is distributed under the University of Illinois Open Source
64302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# License. See LICENSE.TXT for details.
64402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
64502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===------------------------------------------------------------------------===#
64602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
64702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file contains the LLVMBuild project information in a format easily
64802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# consumed by the Makefile based build system.
64902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
65002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file is autogenerated by llvm-build, do not edit!
65102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
65202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===------------------------------------------------------------------------===#
653b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
654b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
65502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
65602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write the dependencies for the fragment.
65702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        #
65802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # FIXME: Technically, we need to properly quote for Make here.
659b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
66002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# Clients must explicitly enable LLVMBUILD_INCLUDE_DEPENDENCIES to get
66102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# these dependencies. This is a compromise to help improve the
662b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# performance of recursive Make systems.
663b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
664b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('ifeq ($(LLVMBUILD_INCLUDE_DEPENDENCIES),1)\n')
665b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("# The dependencies for this Makefile fragment itself.\n")
666b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("%s: \\\n" % (mk_quote_string_for_target(output_path),))
66702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for dep in dependencies:
668b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("\t%s \\\n" % (dep,))
669b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
67002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
67102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Generate dummy rules for each of the dependencies, so that things
67202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # continue to work correctly if any of those files are moved or removed.
673b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
67402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# The dummy targets to allow proper regeneration even when files are moved or
675b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# removed.
676b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
67702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for dep in dependencies:
678b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("%s:\n" % (mk_quote_string_for_target(dep),))
679b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('endif\n')
68002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
68102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        f.close()
68202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
683affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbardef add_magic_target_components(parser, project, opts):
684affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    """add_magic_target_components(project, opts) -> None
685affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
686affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    Add the "magic" target based components to the project, which can only be
687affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    determined based on the target configuration options.
688affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
689affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    This currently is responsible for populating the required_libraries list of
69083337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar    the "all-targets", "Native", "NativeCodeGen", and "Engine" components.
691affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    """
692affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
693affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Determine the available targets.
694affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    available_targets = dict((ci.name,ci)
695affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                             for ci in project.component_infos
696affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                             if ci.type_name == 'TargetGroup')
697affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
698affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the configured native target.
699affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
700affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # We handle a few special cases of target names here for historical
701affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # reasons, as these are the names configure currently comes up with.
702affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_target_name = { 'x86' : 'X86',
703affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                           'x86_64' : 'X86',
704affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                           'Unknown' : None }.get(opts.native_target,
705affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                                                  opts.native_target)
706affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target_name is None:
707affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_target = None
708affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
709affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_target = available_targets.get(native_target_name)
710affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if native_target is None:
711affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            parser.error("invalid native target: %r (not in project)" % (
712affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    opts.native_target,))
713affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if native_target.type_name != 'TargetGroup':
714affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            parser.error("invalid native target: %r (not a target)" % (
715affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    opts.native_target,))
716affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
717affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the list of targets to enable.
718affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if opts.enable_targets is None:
719affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        enable_targets = available_targets.values()
720affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
72183337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        # We support both space separated and semi-colon separated lists.
722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if opts.enable_targets == '':
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            enable_target_names = []
724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        elif ' ' in opts.enable_targets:
72583337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar            enable_target_names = opts.enable_targets.split()
72683337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        else:
72783337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar            enable_target_names = opts.enable_targets.split(';')
72883337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar
729affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        enable_targets = []
73083337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        for name in enable_target_names:
731affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            target = available_targets.get(name)
732affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            if target is None:
733affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                parser.error("invalid target to enable: %r (not in project)" % (
734affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                        name,))
735affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            if target.type_name != 'TargetGroup':
736affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                parser.error("invalid target to enable: %r (not a target)" % (
737affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                        name,))
738affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            enable_targets.append(target)
739affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
740affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the special library groups we are going to populate. We enforce that
741affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # these appear in the project (instead of just adding them) so that they at
742affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # least have an explicit representation in the project LLVMBuild files (and
743affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # comments explaining how they are populated).
744affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    def find_special_group(name):
745affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        info = info_map.get(name)
746affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info is None:
747affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("expected project to contain special %r component" % (
748affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name,))
749affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
750affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.type_name != 'LibraryGroup':
751affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r should be a LibraryGroup" % (
752affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name,))
753affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
754affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.required_libraries:
755affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r must have empty %r list" % (
756affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name, 'required_libraries'))
757affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.add_to_library_groups:
758affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r must have empty %r list" % (
759affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name, 'add_to_library_groups'))
760affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
76154d8c7fc0359cf9a0b857d27ea6816ea6b050281Daniel Dunbar        info._is_special_group = True
762affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        return info
763affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
764affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    info_map = dict((ci.name, ci) for ci in project.component_infos)
765affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    all_targets = find_special_group('all-targets')
766affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_group = find_special_group('Native')
767affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_codegen_group = find_special_group('NativeCodeGen')
768affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    engine_group = find_special_group('Engine')
769affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
770affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Set the enabled bit in all the target groups, and append to the
771affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # all-targets list.
772affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    for ci in enable_targets:
773affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        all_targets.required_libraries.append(ci.name)
774affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        ci.enabled = True
775affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
776affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # If we have a native target, then that defines the native and
777affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # native_codegen libraries.
778affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target and native_target.enabled:
779affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_group.required_libraries.append(native_target.name)
780affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_codegen_group.required_libraries.append(
781affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            '%sCodeGen' % native_target.name)
782affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
783affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # If we have a native target with a JIT, use that for the engine. Otherwise,
784affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # use the interpreter.
785affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target and native_target.enabled and native_target.has_jit:
786affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        engine_group.required_libraries.append('JIT')
787affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        engine_group.required_libraries.append(native_group.name)
788affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
789affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        engine_group.required_libraries.append('Interpreter')
790affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
791ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbardef main():
792ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    from optparse import OptionParser, OptionGroup
793ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    parser = OptionParser("usage: %prog [options]")
7941e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
7951e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group = OptionGroup(parser, "Input Options")
7961e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--source-root", dest="source_root", metavar="PATH",
797ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                      help="Path to the LLVM source (inferred if not given)",
798ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                      action="store", default=None)
7991e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--llvmbuild-source-root",
8001e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="llvmbuild_source_root",
8011e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help=(
8021e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar            "If given, an alternate path to search for LLVMBuild.txt files"),
8031e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None, metavar="PATH")
804b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    group.add_option("", "--build-root", dest="build_root", metavar="PATH",
805b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      help="Path to the build directory (if needed) [%default]",
806b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      action="store", default=None)
8071e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
8081e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
8091e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group = OptionGroup(parser, "Output Options")
8101e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--print-tree", dest="print_tree",
8111e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Print out the project component tree [%default]",
8121e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store_true", default=False)
8131e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-llvmbuild", dest="write_llvmbuild",
81443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                      help="Write out the LLVMBuild.txt files to PATH",
81543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                      action="store", default=None, metavar="PATH")
8161e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-library-table",
8171e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="write_library_table", metavar="PATH",
8181e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the C++ library dependency table to PATH",
8191e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
8201e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-cmake-fragment",
8211e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="write_cmake_fragment", metavar="PATH",
8221e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the CMake project information to PATH",
8231e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    group.add_option("", "--write-cmake-exports-fragment",
82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     dest="write_cmake_exports_fragment", metavar="PATH",
82636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     help="Write the CMake exports information to PATH",
82736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     action="store", default=None)
8281e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-make-fragment",
82902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                      dest="write_make_fragment", metavar="PATH",
8301e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the Makefile project information to PATH",
8311e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
832b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    group.add_option("", "--configure-target-def-file",
833b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     dest="configure_target_def_files",
834b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     help="""Configure the given file at SUBPATH (relative to
835b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarthe inferred or given source root, and with a '.in' suffix) by replacing certain
836b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarsubstitution variables with lists of targets that support certain features (for
837b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarexample, targets with AsmPrinters) and write the result to the build root (as
838b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbargiven by --build-root) at the same SUBPATH""",
839b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     metavar="SUBPATH", action="append", default=None)
8401e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
841affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
842affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group = OptionGroup(parser, "Configuration Options")
843affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group.add_option("", "--native-target",
844affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      dest="native_target", metavar="NAME",
845affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      help=("Treat the named target as the 'native' one, if "
846affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                            "given [%default]"),
847affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      action="store", default=None)
848affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group.add_option("", "--enable-targets",
849affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      dest="enable_targets", metavar="NAMES",
85083337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar                      help=("Enable the given space or semi-colon separated "
85183337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar                            "list of targets, or all targets if not present"),
85202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                      action="store", default=None)
853754935418133ece1f51d1857a61d538797c34891Preston Gurd    group.add_option("", "--enable-optional-components",
854754935418133ece1f51d1857a61d538797c34891Preston Gurd                      dest="optional_components", metavar="NAMES",
855754935418133ece1f51d1857a61d538797c34891Preston Gurd                      help=("Enable the given space or semi-colon separated "
856754935418133ece1f51d1857a61d538797c34891Preston Gurd                            "list of optional components"),
857b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                      action="store", default="")
8581e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
8591e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
860ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    (opts, args) = parser.parse_args()
861ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
862ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    # Determine the LLVM source path, if not given.
863ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    source_root = opts.source_root
864ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    if source_root:
865c2c50cdcdc19a1bca993c06d13d8cdca87083ce4Chandler Carruth        if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
866ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                                           'Function.cpp')):
867ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar            parser.error('invalid LLVM source root: %r' % source_root)
868ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    else:
869ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        llvmbuild_path = os.path.dirname(__file__)
870ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        llvm_build_path = os.path.dirname(llvmbuild_path)
871ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        utils_path = os.path.dirname(llvm_build_path)
872ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        source_root = os.path.dirname(utils_path)
873c2c50cdcdc19a1bca993c06d13d8cdca87083ce4Chandler Carruth        if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
874ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                                           'Function.cpp')):
875ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar            parser.error('unable to infer LLVM source root, please specify')
876ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
877df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    # Construct the LLVM project information.
878df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    llvmbuild_source_root = opts.llvmbuild_source_root or source_root
879df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    project_info = LLVMProjectInfo.load_from_path(
880df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        source_root, llvmbuild_source_root)
881df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
882affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Add the magic target based components.
883affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    add_magic_target_components(parser, project_info, opts)
884affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
885b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    # Validate the project component info.
886b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    project_info.validate_components()
887b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
88800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    # Print the component tree, if requested.
88900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    if opts.print_tree:
89000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        project_info.print_tree()
89100b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
89243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    # Write out the components, if requested. This is useful for auto-upgrading
89343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    # the schema.
89443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    if opts.write_llvmbuild:
89543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        project_info.write_components(opts.write_llvmbuild)
89643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
8971688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the required library table, if requested.
898efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar    if opts.write_library_table:
899754935418133ece1f51d1857a61d538797c34891Preston Gurd        project_info.write_library_table(opts.write_library_table,
900754935418133ece1f51d1857a61d538797c34891Preston Gurd                                         opts.optional_components)
901efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
9021688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the make fragment, if requested.
90302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar    if opts.write_make_fragment:
90402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        project_info.write_make_fragment(opts.write_make_fragment)
90502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
9061688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the cmake fragment, if requested.
9071688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    if opts.write_cmake_fragment:
9081688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        project_info.write_cmake_fragment(opts.write_cmake_fragment)
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if opts.write_cmake_exports_fragment:
91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment)
9111688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
912b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    # Configure target definition files, if requested.
913b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    if opts.configure_target_def_files:
914b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Verify we were given a build root.
915b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        if not opts.build_root:
916b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            parser.error("must specify --build-root when using "
917b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                         "--configure-target-def-file")
918b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
919b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Create the substitution list.
920b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        available_targets = [ci for ci in project_info.component_infos
921b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                             if ci.type_name == 'TargetGroup']
922b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        substitutions = [
923b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_TARGETS@",
924b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_TARGET(%s)' % ci.name
925b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets)),
926b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_ASM_PRINTERS@",
927b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_ASM_PRINTER(%s)' % ci.name
928b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
929b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_asmprinter)),
930b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_ASM_PARSERS@",
931b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_ASM_PARSER(%s)' % ci.name
932b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
933b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_asmparser)),
934b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_DISASSEMBLERS@",
935b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_DISASSEMBLER(%s)' % ci.name
936b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
937b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_disassembler))]
938b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
939b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Configure the given files.
940b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        for subpath in opts.configure_target_def_files:
941b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            inpath = os.path.join(source_root, subpath + '.in')
942b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            outpath = os.path.join(opts.build_root, subpath)
943b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            result = configutil.configure_file(inpath, outpath, substitutions)
944b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            if not result:
945b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                note("configured file %r hasn't changed" % outpath)
946b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
947ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbarif __name__=='__main__':
948ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    main()
949