1b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarfrom __future__ import absolute_import
237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimport filecmp
3ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbarimport os
41cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbarimport sys
5ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
6b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarimport llvmbuild.componentinfo as componentinfo
7b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarimport llvmbuild.configutil as configutil
8df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesfrom llvmbuild.util import fatal, note
101cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
111cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar###
121cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1357574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbardef cmake_quote_string(value):
1457574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    """
1557574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    cmake_quote_string(value) -> str
1657574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
1757574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    Return a quoted form of the given value that is suitable for use in CMake
1857574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    language files.
1957574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    """
2057574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
2157574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    # Currently, we only handle escaping backslashes.
2257574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    value = value.replace("\\", "\\\\")
2357574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
2457574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar    return value
2557574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
26d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbardef cmake_quote_path(value):
27d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    """
28d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    cmake_quote_path(value) -> str
29d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
30d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    Return a quoted form of the given value that is suitable for use in CMake
31d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    language files.
32d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    """
33d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
34d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # CMake has a bug in it's Makefile generator that doesn't properly quote
35d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # strings it generates. So instead of using proper quoting, we just use "/"
36d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    # style paths.  Currently, we only handle escaping backslashes.
37d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    value = value.replace("\\", "/")
38d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
39d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar    return value
40d5889d8c7fcd97994cf38bb7469a703fe3db3672Daniel Dunbar
4120fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbardef mk_quote_string_for_target(value):
4220fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    """
4320fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    mk_quote_string_for_target(target_name) -> str
4420fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Return a quoted form of the given target_name suitable for including in a
4620fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    Makefile as a target name.
4720fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    """
4820fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
4920fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    # The only quoting we currently perform is for ':', to support msys users.
5020fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar    return value.replace(":", "\\:")
5120fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
52195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbardef make_install_dir(path):
53195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    """
54195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    make_install_dir(path) -> None
55195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
56195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    Create the given directory path for installation, including any parents.
57195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    """
58195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
59d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    # os.makedirs considers it an error to be called with an existent path.
60195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar    if not os.path.exists(path):
61195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        os.makedirs(path)
62195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar
6320fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar###
6420fb32b3922ea23d4c83b2c54c565bdf95bb4ad5Daniel Dunbar
65df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbarclass LLVMProjectInfo(object):
66df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    @staticmethod
67df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def load_infos_from_path(llvmbuild_source_root):
68e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar        def recurse(subpath):
69e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Load the LLVMBuild file.
70e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            llvmbuild_path = os.path.join(llvmbuild_source_root + subpath,
71e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                                          'LLVMBuild.txt')
72e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            if not os.path.exists(llvmbuild_path):
73e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                fatal("missing LLVMBuild.txt file at: %r" % (llvmbuild_path,))
74e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
75e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Parse the components from it.
76e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            common,info_iter = componentinfo.load_from_path(llvmbuild_path,
77e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                                                            subpath)
78e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            for info in info_iter:
79df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar                yield info
80df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
81e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            # Recurse into the specified subdirectories.
82e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar            for subdir in common.get_list("subdirectories"):
83e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                for item in recurse(os.path.join(subpath, subdir)):
84e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar                    yield item
85e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
86e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar        return recurse("/")
87e5609abccbd329ef4b07270c8b71a5b59cfe8bceDaniel Dunbar
88df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    @staticmethod
89df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def load_from_path(source_root, llvmbuild_source_root):
90df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        infos = list(
91df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar            LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root))
92df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
93df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        return LLVMProjectInfo(source_root, infos)
94df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
95df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    def __init__(self, source_root, component_infos):
961cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Store our simple ivars.
97df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        self.source_root = source_root
98b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.component_infos = list(component_infos)
99b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.component_info_map = None
100b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        self.ordered_component_infos = None
101b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
102b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    def validate_components(self):
103b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        """validate_components() -> None
104b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
105b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        Validate that the project components are well-defined. Among other
106b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        things, this checks that:
107b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar          - Components have valid references.
108b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar          - Components references do not form cycles.
109b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
110b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        We also construct the map from component names to info, and the
111b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        topological ordering of components.
112b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        """
113df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
1141cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Create the component info map and validate that component names are
1151cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # unique.
1161cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        self.component_info_map = {}
117b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar        for ci in self.component_infos:
1181cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            existing = self.component_info_map.get(ci.name)
1191cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if existing is not None:
1201cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # We found a duplicate component name, report it and error out.
1211cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                fatal("found duplicate component %r (at %r and %r)" % (
1221cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                        ci.name, ci.subpath, existing.subpath))
1231cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            self.component_info_map[ci.name] = ci
1241cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
125efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Disallow 'all' as a component name, which is a special case.
126efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        if 'all' in self.component_info_map:
127efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            fatal("project is not allowed to define 'all' component")
128efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
12900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        # Add the root component.
13086c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        if '$ROOT' in self.component_info_map:
13186c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            fatal("project is not allowed to define $ROOT component")
13286c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        self.component_info_map['$ROOT'] = componentinfo.GroupComponentInfo(
13386c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            '/', '$ROOT', None)
13400b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        self.component_infos.append(self.component_info_map['$ROOT'])
13586c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1361cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # Topologically order the component information according to their
1371cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        # component references.
1381cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        def visit_component_info(ci, current_stack, current_set):
1391cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Check for a cycles.
1401cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if ci in current_set:
1411cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # We found a cycle, report it and error out.
1421cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                cycle_description = ' -> '.join(
1431cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    '%r (%s)' % (ci.name, relation)
1441cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    for relation,ci in current_stack)
1451cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                fatal("found cycle to %r after following: %s -> %s" % (
1461cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                        ci.name, cycle_description, ci.name))
1471cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1481cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # If we have already visited this item, we are done.
1491cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            if ci not in components_to_visit:
1501cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                return
1511cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1521cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Otherwise, mark the component info as visited and traverse.
1531cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            components_to_visit.remove(ci)
1541cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
15586c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar            # Validate the parent reference, which we treat specially.
15600b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            if ci.parent is not None:
15700b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                parent = self.component_info_map.get(ci.parent)
15800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                if parent is None:
15900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                    fatal("component %r has invalid reference %r (via %r)" % (
16000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                            ci.name, ci.parent, 'parent'))
16100b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                ci.set_parent_instance(parent)
16286c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1631cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            for relation,referent_name in ci.get_component_references():
1641cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # Validate that the reference is ok.
1651cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                referent = self.component_info_map.get(referent_name)
1661cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                if referent is None:
1671cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                    fatal("component %r has invalid reference %r (via %r)" % (
1681cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                            ci.name, referent_name, relation))
1691cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1701cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                # Visit the reference.
1711cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_stack.append((relation,ci))
1721cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_set.add(ci)
1731cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                visit_component_info(referent, current_stack, current_set)
1741cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_set.remove(ci)
1751cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar                current_stack.pop()
1761cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
1771cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            # Finally, add the component info to the ordered list.
1781cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar            self.ordered_component_infos.append(ci)
1791cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
18086c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # FIXME: We aren't actually correctly checking for cycles along the
18186c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # parent edges. Haven't decided how I want to handle this -- I thought
18286c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # about only checking cycles by relation type. If we do that, it falls
18386c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar        # out easily. If we don't, we should special case the check.
18486c119a507570144b02645dd262e7d0b8864aa2dDaniel Dunbar
1851cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        self.ordered_component_infos = []
186da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi        components_to_visit = sorted(
187da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi            set(self.component_infos),
188da5cd6a180f8174685aaa3fc0b92e171ec032f4cNAKAMURA Takumi            key = lambda c: c.name)
1891cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar        while components_to_visit:
190b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            visit_component_info(components_to_visit[0], [], set())
1911cf14aff1bd7aa9343262f26f39c7f10fae68c0eDaniel Dunbar
19200b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        # Canonicalize children lists.
19300b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        for c in self.ordered_component_infos:
19400b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            c.children.sort(key = lambda c: c.name)
19500b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
19600b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    def print_tree(self):
19700b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        def visit(node, depth = 0):
198b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            print('%s%-40s (%s)' % ('  '*depth, node.name, node.type_name))
19900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar            for c in node.children:
20000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar                visit(c, depth + 1)
20100b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        visit(self.component_info_map['$ROOT'])
20200b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
20343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    def write_components(self, output_path):
20443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # Organize all the components by the directory their LLVMBuild file
20543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # should go in.
20643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        info_basedir = {}
20743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        for ci in self.component_infos:
20843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Ignore the $ROOT component.
20943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if ci.parent is None:
21043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                continue
21143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
21243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            info_basedir[ci.subpath] = info_basedir.get(ci.subpath, []) + [ci]
21343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
214b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        # Compute the list of subdirectories to scan.
215b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        subpath_subdirs = {}
216b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar        for ci in self.component_infos:
217b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Ignore root components.
218b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            if ci.subpath == '/':
219b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                continue
220b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
221b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Otherwise, append this subpath to the parent list.
222b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            parent_path = os.path.dirname(ci.subpath)
223b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            subpath_subdirs[parent_path] = parent_list = subpath_subdirs.get(
224b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                parent_path, set())
225b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            parent_list.add(os.path.basename(ci.subpath))
226b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
22743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        # Generate the build files.
22843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        for subpath, infos in info_basedir.items():
22943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Order the components by name to have a canonical ordering.
23043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            infos.sort(key = lambda ci: ci.name)
23143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
23243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Format the components into llvmbuild fragments.
233b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            fragments = []
234b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
235b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Add the common fragments.
236b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            subdirectories = subpath_subdirs.get(subpath)
237b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            if subdirectories:
238b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragment = """\
239b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbarsubdirectories = %s
240b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar""" % (" ".join(sorted(subdirectories)),)
241b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragments.append(("common", fragment))
242b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
243b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Add the component fragments.
244b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            num_common_fragments = len(fragments)
245b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            for ci in infos:
246b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragment = ci.get_llvmbuild_fragment()
247b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                if fragment is None:
248b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                    continue
249b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
250b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                name = "component_%d" % (len(fragments) - num_common_fragments)
251b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                fragments.append((name, fragment))
252b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
25343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if not fragments:
25443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                continue
25543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
25643120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            assert subpath.startswith('/')
25743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            directory_path = os.path.join(output_path, subpath[1:])
25843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
25943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            # Create the directory if it does not already exist.
26043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            if not os.path.exists(directory_path):
26143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                os.makedirs(directory_path)
26243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
263a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # In an effort to preserve comments (which aren't parsed), read in
264a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # the original file and extract the comments. We only know how to
265a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # associate comments that prefix a section name.
266a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            f = open(infos[0]._source_path)
267a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            comments_map = {}
268a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            comment_block = ""
269a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            for ln in f:
270a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                if ln.startswith(';'):
271a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    comment_block += ln
272a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                elif ln.startswith('[') and ln.endswith(']\n'):
273b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                    comments_map[ln[1:-2]] = comment_block
274a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                else:
275a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    comment_block = ""
276a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            f.close()
277a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar
278a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar            # Create the LLVMBuild fil[e.
27943120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            file_path = os.path.join(directory_path, 'LLVMBuild.txt')
28043120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            f = open(file_path, "w")
281fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar
282fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            # Write the header.
283fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_fmt = ';===- %s %s-*- Conf -*--===;'
284fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_name = '.' + os.path.join(subpath, 'LLVMBuild.txt')
285fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
286fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar            header_string = header_fmt % (header_name, header_pad)
287b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
288fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar%s
289fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
290fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;                     The LLVM Compiler Infrastructure
291fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
292fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; This file is distributed under the University of Illinois Open Source
293fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; License. See LICENSE.TXT for details.
294fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
295fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;===------------------------------------------------------------------------===;
296fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
297fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; This is an LLVMBuild description file for the components in this subdirectory.
298fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
299fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar; For more information on the LLVMBuild system, please see:
300fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
301fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;   http://llvm.org/docs/LLVMBuild.html
302fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;
303fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar;===------------------------------------------------------------------------===;
304b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
305b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
306fb6d79a58e710b3b4aef34ecacc28603b6d5042eDaniel Dunbar
307b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            # Write out each fragment.each component fragment.
308b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar            for name,fragment in fragments:
309a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                comment = comments_map.get(name)
310a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                if comment is not None:
311a3217165c6d2ef7caf58665eb0a61c64ab229b9fDaniel Dunbar                    f.write(comment)
312b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                f.write("[%s]\n" % name)
31343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                f.write(fragment)
314b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar                if fragment is not fragments[-1][1]:
315b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                    f.write('\n')
316b0c594fd422417e1e290da166b566c7bee74644bDaniel Dunbar
31743120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar            f.close()
31843120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
319754935418133ece1f51d1857a61d538797c34891Preston Gurd    def write_library_table(self, output_path, enabled_optional_components):
320efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Write out the mapping from component names to required libraries.
321efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        #
322efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # We do this in topological order so that we know we can append the
323efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # dependencies for added library groups.
324efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        entries = {}
325efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        for c in self.ordered_component_infos:
326177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            # Skip optional components which are not enabled.
327754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name == 'OptionalLibrary' \
328754935418133ece1f51d1857a61d538797c34891Preston Gurd                and c.name not in enabled_optional_components:
329754935418133ece1f51d1857a61d538797c34891Preston Gurd                continue
330754935418133ece1f51d1857a61d538797c34891Preston Gurd
331177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            # Skip target groups which are not enabled.
332177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            tg = c.get_parent_target_group()
333177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar            if tg and not tg.enabled:
334177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar                continue
335177a119621f14a6ced87982ada75372815b636cfDaniel Dunbar
336c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar            # Only certain components are in the table.
337754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name not in ('Library', 'OptionalLibrary', \
338754935418133ece1f51d1857a61d538797c34891Preston Gurd                                   'LibraryGroup', 'TargetGroup'):
339efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                continue
340efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
341efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Compute the llvm-config "component name". For historical reasons,
342efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # this is lowercased based on the library name.
343efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            llvmconfig_component_name = c.get_llvmconfig_component_name()
34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
345efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Get the library name, or None for LibraryGroups.
346754935418133ece1f51d1857a61d538797c34891Preston Gurd            if c.type_name == 'Library' or c.type_name == 'OptionalLibrary':
347bb53bbb7d4b1ac3da416d922101d4cbc280b145cDaniel Dunbar                library_name = c.get_prefixed_library_name()
348b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                is_installed = c.installed
349c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar            else:
350c352caf168094c83f05a8010ca14c2e643dbf618Daniel Dunbar                library_name = None
351b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                is_installed = True
352efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
353efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Get the component names of all the required libraries.
354efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            required_llvmconfig_component_names = [
355efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                self.component_info_map[dep].get_llvmconfig_component_name()
356efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                for dep in c.required_libraries]
357efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
358efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Insert the entries for library groups we should add to.
359efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            for dep in c.add_to_library_groups:
360efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                entries[dep][2].append(llvmconfig_component_name)
361efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
362efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            # Add the entry.
363efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            entries[c.name] = (llvmconfig_component_name, library_name,
364b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                               required_llvmconfig_component_names,
365b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                               is_installed)
366efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
367efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Convert to a list of entries and sort by name.
368b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        entries = list(entries.values())
369efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
370efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Create an 'all' pseudo component. We keep the dependency list small by
371efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # only listing entries that have no other dependents.
372efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        root_entries = set(e[0] for e in entries)
373b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        for _,_,deps,_ in entries:
374efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            root_entries -= set(deps)
375b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        entries.append(('all', None, root_entries, True))
376efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
377efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        entries.sort()
378efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
379efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Compute the maximum number of required libraries, plus one so there is
380efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # always a sentinel.
381efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        max_required_libraries = max(len(deps)
382b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                                     for _,_,deps,_ in entries) + 1
383efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
384efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        # Write out the library table.
385195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        f = open(output_path+'.new', 'w')
387b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
388efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//===- llvm-build generated file --------------------------------*- C++ -*-===//
389efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
390efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar// Component Library Depenedency Table
391efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
392efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar// Automatically generated file, do not edit!
393efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//
394efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar//===----------------------------------------------------------------------===//
395b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
396b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
397b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('struct AvailableComponent {\n')
398b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// The name of the component.\n')
399b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *Name;\n')
400b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
401b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// The name of the library for this component (or NULL).\n')
402b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *Library;\n')
403b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
404b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  /// Whether the component is installed.\n')
405b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  bool IsInstalled;\n')
406b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
407b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\
408b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar  /// The list of libraries required when linking this component.\n')
409b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('  const char *RequiredLibraries[%d];\n' % (
410b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            max_required_libraries))
411b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('} AvailableComponents[%d] = {\n' % len(entries))
412b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar        for name,library_name,required_names,is_installed in entries:
413efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            if library_name is None:
414efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                library_name_as_cstr = '0'
415efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar            else:
416bb53bbb7d4b1ac3da416d922101d4cbc280b145cDaniel Dunbar                library_name_as_cstr = '"lib%s.a"' % library_name
417b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write('  { "%s", %s, %d, { %s } },\n' % (
418b5cd41e26f89aad2f2dc4f5dc37577f7abf8528aDaniel Dunbar                name, library_name_as_cstr, is_installed,
419efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar                ', '.join('"%s"' % dep
420b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                          for dep in required_names)))
421b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('};\n')
422efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar        f.close()
423efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if not os.path.isfile(output_path):
42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            os.rename(output_path+'.new', output_path)
42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        elif filecmp.cmp(output_path, output_path+'.new'):
42737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            os.remove(output_path+'.new')
42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        else:
42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            os.remove(output_path)
43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            os.rename(output_path+'.new', output_path)
43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4325086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar    def get_required_libraries_for_component(self, ci, traverse_groups = False):
4335086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        """
4345086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        get_required_libraries_for_component(component_info) -> iter
4355086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4365086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        Given a Library component info descriptor, return an iterator over all
4375086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        of the directly required libraries for linking with this component. If
4385086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        traverse_groups is True, then library and target groups will be
4395086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        traversed to include their required libraries.
4405086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        """
4415086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        assert ci.type_name in ('Library', 'OptionalLibrary', 'LibraryGroup', 'TargetGroup')
4435086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4445086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        for name in ci.required_libraries:
4455086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # Get the dependency info.
4465086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            dep = self.component_info_map[name]
4475086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4485086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # If it is a library, yield it.
44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if dep.type_name == 'Library' or dep.type_name == 'OptionalLibrary':
4505086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                yield dep
4515086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                continue
4525086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4535086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # Otherwise if it is a group, yield or traverse depending on what
4545086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            # was requested.
4555086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar            if dep.type_name in ('LibraryGroup', 'TargetGroup'):
4565086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                if not traverse_groups:
4575086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    yield dep
4585086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    continue
4595086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4605086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                for res in self.get_required_libraries_for_component(dep, True):
4615086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                    yield res
4625086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
4631688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    def get_fragment_dependencies(self):
46402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        """
4651688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        get_fragment_dependencies() -> iter
46602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
4671688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Compute the list of files (as absolute paths) on which the output
4681688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        fragments depend (i.e., files for which a modification should trigger a
4691688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        rebuild of the fragment).
47002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        """
47102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
47202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Construct a list of all the dependencies of the Makefile fragment
47302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # itself. These include all the LLVMBuild files themselves, as well as
47402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # all of our own sources.
475309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        #
476309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        # Many components may come from the same file, so we make sure to unique
477309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        # these.
478309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar        build_paths = set()
47902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for ci in self.component_infos:
480309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar            p = os.path.join(self.source_root, ci.subpath[1:], 'LLVMBuild.txt')
481309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar            if p not in build_paths:
482309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar                yield p
483309fc86e7c2b7ef805e75ff2be1da8d3f6b920d5Daniel Dunbar                build_paths.add(p)
48402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
48502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Gather the list of necessary sources by just finding all loaded
48602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # modules that are inside the LLVM source tree.
48702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for module in sys.modules.values():
48802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # Find the module path.
48902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if not hasattr(module, '__file__'):
49002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                continue
49102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            path = getattr(module, '__file__')
49202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if not path:
49302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                continue
49402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
49502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # Strip off any compiled suffix.
49602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
49702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                path = path[:-1]
49802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
49902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # If the path exists and is in the source tree, consider it a
50002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            # dependency.
50102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar            if (path.startswith(self.source_root) and os.path.exists(path)):
5021688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar                yield path
5031688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def write_cmake_fragment(self, output_path, enabled_optional_components):
5051688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
5061688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        write_cmake_fragment(output_path) -> None
5071688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5081688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Generate a CMake fragment which includes all of the collated LLVMBuild
5091688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        information in a format that is easily digestible by a CMake. The exact
5101688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        contents of this are closely tied to how the CMake configuration
5111688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        integrates LLVMBuild, see CMakeLists.txt in the top-level.
5121688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
5131688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5141688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        dependencies = list(self.get_fragment_dependencies())
5151688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5161688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write out the CMake fragment.
517195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
5181688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        f = open(output_path, 'w')
5191688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5201688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write the header.
5211688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_fmt = '\
5221688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#'
5231688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_name = os.path.basename(output_path)
5241688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
5251688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        header_string = header_fmt % (header_name, header_pad)
526b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
5271688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar%s
5281688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5291688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#                     The LLVM Compiler Infrastructure
5301688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5311688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file is distributed under the University of Illinois Open Source
5321688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# License. See LICENSE.TXT for details.
5331688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5341688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===------------------------------------------------------------------------===#
5351688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5361688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file contains the LLVMBuild project information in a format easily
5371688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# consumed by the CMake based build system.
5381688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5391688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# This file is autogenerated by llvm-build, do not edit!
5401688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5411688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#===------------------------------------------------------------------------===#
542b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
543b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
5441688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
5451688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        # Write the dependency information in the best way we can.
546b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""
5471688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# LLVMBuild CMake fragment dependencies.
5481688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5491688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# CMake has no builtin way to declare that the configuration depends on
5501688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# a particular file. However, a side effect of configure_file is to add
5511688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# said input file to CMake's internal dependency list. So, we use that
5521688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# and a dummy output file to communicate the dependency information to
5531688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# CMake.
5541688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar#
5551688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar# FIXME: File a CMake RFE to get a properly supported version of this
556b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# feature.
557b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
5581688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        for dep in dependencies:
559b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
5601688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbarconfigure_file(\"%s\"
561b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar               ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % (
562b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                cmake_quote_path(dep),))
56357574fa35e3fe766b5a5cc6becd9b56ae0aed17aDaniel Dunbar
5645086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        # Write the properties we use to encode the required library dependency
5655086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        # information in a form CMake can easily use directly.
566b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""
5675086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar# Explicit library dependency information.
5685086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar#
5695086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar# The following property assignments effectively create a map from component
570b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# names to required libraries, in a way that is easily accessed from CMake.
571b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
5725086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar        for ci in self.ordered_component_infos:
57337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            # Skip optional components which are not enabled.
57437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if ci.type_name == 'OptionalLibrary' \
57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                and ci.name not in enabled_optional_components:
57637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                continue
57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
57837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            # We only write the information for certain components currently.
57937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if ci.type_name not in ('Library', 'OptionalLibrary'):
5805086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                continue
5815086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
582b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("""\
583b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbarset_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
5845086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                ci.get_prefixed_library_name(), " ".join(sorted(
5855086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar                     dep.get_prefixed_library_name()
586b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                     for dep in self.get_required_libraries_for_component(ci)))))
5875086de6f878187f4419351b2b24c766e0d0d25dcDaniel Dunbar
5881688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        f.close()
5891688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def write_cmake_exports_fragment(self, output_path, enabled_optional_components):
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        """
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        write_cmake_exports_fragment(output_path) -> None
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Generate a CMake fragment which includes LLVMBuild library
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        dependencies expressed similarly to how CMake would write
59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        them via install(EXPORT).
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        """
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        dependencies = list(self.get_fragment_dependencies())
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        # Write out the CMake exports fragment.
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        make_install_dir(os.path.dirname(output_path))
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f = open(output_path, 'w')
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f.write("""\
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# Explicit library dependency information.
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# The following property assignments tell CMake about link
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# dependencies of libraries imported from LLVM.
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines""")
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for ci in self.ordered_component_infos:
61237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            # Skip optional components which are not enabled.
61337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if ci.type_name == 'OptionalLibrary' \
61437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                and ci.name not in enabled_optional_components:
61537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                continue
61637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            # We only write the information for libraries currently.
61837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if ci.type_name not in ('Library', 'OptionalLibrary'):
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                continue
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            # Skip disabled targets.
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            tg = ci.get_parent_target_group()
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if tg and not tg.enabled:
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                continue
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            f.write("""\
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesset_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                ci.get_prefixed_library_name(), " ".join(sorted(
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     dep.get_prefixed_library_name()
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     for dep in self.get_required_libraries_for_component(ci)))))
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        f.close()
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6341688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    def write_make_fragment(self, output_path):
6351688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
6361688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        write_make_fragment(output_path) -> None
6371688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
6381688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Generate a Makefile fragment which includes all of the collated
6391688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        LLVMBuild information in a format that is easily digestible by a
6401688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Makefile. The exact contents of this are closely tied to how the LLVM
6411688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        Makefiles integrate LLVMBuild, see Makefile.rules in the top-level.
6421688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        """
6431688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
6441688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar        dependencies = list(self.get_fragment_dependencies())
64502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
64602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write out the Makefile fragment.
647195c6f36634ae1579d4457c188d9b058fbab9973Daniel Dunbar        make_install_dir(os.path.dirname(output_path))
64802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        f = open(output_path, 'w')
64902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
65002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write the header.
65102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_fmt = '\
65202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===-- %s - LLVMBuild Configuration for LLVM %s-*- Makefile -*--===#'
65302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_name = os.path.basename(output_path)
65402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
65502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        header_string = header_fmt % (header_name, header_pad)
656b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
65702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar%s
65802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
65902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#                     The LLVM Compiler Infrastructure
66002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
66102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file is distributed under the University of Illinois Open Source
66202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# License. See LICENSE.TXT for details.
66302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
66402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===------------------------------------------------------------------------===#
66502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
66602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file contains the LLVMBuild project information in a format easily
66702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# consumed by the Makefile based build system.
66802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
66902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# This file is autogenerated by llvm-build, do not edit!
67002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#
67102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar#===------------------------------------------------------------------------===#
672b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar
673b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""" % header_string)
67402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
67502271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Write the dependencies for the fragment.
67602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        #
67702271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # FIXME: Technically, we need to properly quote for Make here.
678b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
67902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# Clients must explicitly enable LLVMBUILD_INCLUDE_DEPENDENCIES to get
68002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# these dependencies. This is a compromise to help improve the
681b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# performance of recursive Make systems.
682b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
683b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('ifeq ($(LLVMBUILD_INCLUDE_DEPENDENCIES),1)\n')
684b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("# The dependencies for this Makefile fragment itself.\n")
685b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("%s: \\\n" % (mk_quote_string_for_target(output_path),))
68602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for dep in dependencies:
687b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("\t%s \\\n" % (dep,))
688b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('\n')
68902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
69002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # Generate dummy rules for each of the dependencies, so that things
69102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        # continue to work correctly if any of those files are moved or removed.
692b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write("""\
69302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar# The dummy targets to allow proper regeneration even when files are moved or
694b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar# removed.
695b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar""")
69602271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        for dep in dependencies:
697b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar            f.write("%s:\n" % (mk_quote_string_for_target(dep),))
698b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar        f.write('endif\n')
69902271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
70002271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        f.close()
70102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
702affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbardef add_magic_target_components(parser, project, opts):
703affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    """add_magic_target_components(project, opts) -> None
704affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
705affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    Add the "magic" target based components to the project, which can only be
706affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    determined based on the target configuration options.
707affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
708affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    This currently is responsible for populating the required_libraries list of
70983337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar    the "all-targets", "Native", "NativeCodeGen", and "Engine" components.
710affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    """
711affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
712affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Determine the available targets.
713affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    available_targets = dict((ci.name,ci)
714affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                             for ci in project.component_infos
715affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                             if ci.type_name == 'TargetGroup')
716affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
717affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the configured native target.
718affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
719affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # We handle a few special cases of target names here for historical
720affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # reasons, as these are the names configure currently comes up with.
721affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_target_name = { 'x86' : 'X86',
722affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                           'x86_64' : 'X86',
723affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                           'Unknown' : None }.get(opts.native_target,
724affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                                                  opts.native_target)
725affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target_name is None:
726affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_target = None
727affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
728affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_target = available_targets.get(native_target_name)
729affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if native_target is None:
730affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            parser.error("invalid native target: %r (not in project)" % (
731affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    opts.native_target,))
732affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if native_target.type_name != 'TargetGroup':
733affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            parser.error("invalid native target: %r (not a target)" % (
734affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    opts.native_target,))
735affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
736affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the list of targets to enable.
737affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if opts.enable_targets is None:
738affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        enable_targets = available_targets.values()
739affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
74083337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        # We support both space separated and semi-colon separated lists.
741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if opts.enable_targets == '':
742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            enable_target_names = []
743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        elif ' ' in opts.enable_targets:
74483337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar            enable_target_names = opts.enable_targets.split()
74583337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        else:
74683337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar            enable_target_names = opts.enable_targets.split(';')
74783337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar
748affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        enable_targets = []
74983337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar        for name in enable_target_names:
750affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            target = available_targets.get(name)
751affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            if target is None:
752affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                parser.error("invalid target to enable: %r (not in project)" % (
753affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                        name,))
754affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            if target.type_name != 'TargetGroup':
755affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                parser.error("invalid target to enable: %r (not a target)" % (
756affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                        name,))
757affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            enable_targets.append(target)
758affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
759affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Find the special library groups we are going to populate. We enforce that
760affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # these appear in the project (instead of just adding them) so that they at
761affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # least have an explicit representation in the project LLVMBuild files (and
762affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # comments explaining how they are populated).
763affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    def find_special_group(name):
764affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        info = info_map.get(name)
765affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info is None:
766affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("expected project to contain special %r component" % (
767affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name,))
768affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
769affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.type_name != 'LibraryGroup':
770affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r should be a LibraryGroup" % (
771affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name,))
772affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
773affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.required_libraries:
774affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r must have empty %r list" % (
775affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name, 'required_libraries'))
776affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        if info.add_to_library_groups:
777affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            fatal("special component %r must have empty %r list" % (
778affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                    name, 'add_to_library_groups'))
779affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
78054d8c7fc0359cf9a0b857d27ea6816ea6b050281Daniel Dunbar        info._is_special_group = True
781affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        return info
782affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
783affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    info_map = dict((ci.name, ci) for ci in project.component_infos)
784affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    all_targets = find_special_group('all-targets')
785affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_group = find_special_group('Native')
786affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    native_codegen_group = find_special_group('NativeCodeGen')
787affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    engine_group = find_special_group('Engine')
788affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
789affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Set the enabled bit in all the target groups, and append to the
790affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # all-targets list.
791affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    for ci in enable_targets:
792affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        all_targets.required_libraries.append(ci.name)
793affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        ci.enabled = True
794affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
795affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # If we have a native target, then that defines the native and
796affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # native_codegen libraries.
797affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target and native_target.enabled:
798affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_group.required_libraries.append(native_target.name)
799affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        native_codegen_group.required_libraries.append(
800affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar            '%sCodeGen' % native_target.name)
801affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
802affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # If we have a native target with a JIT, use that for the engine. Otherwise,
803affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # use the interpreter.
804affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    if native_target and native_target.enabled and native_target.has_jit:
80537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        engine_group.required_libraries.append('MCJIT')
806affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        engine_group.required_libraries.append(native_group.name)
807affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    else:
808affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar        engine_group.required_libraries.append('Interpreter')
809affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
810ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbardef main():
811ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    from optparse import OptionParser, OptionGroup
812ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    parser = OptionParser("usage: %prog [options]")
8131e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
8141e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group = OptionGroup(parser, "Input Options")
8151e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--source-root", dest="source_root", metavar="PATH",
816ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                      help="Path to the LLVM source (inferred if not given)",
817ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                      action="store", default=None)
8181e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--llvmbuild-source-root",
8191e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="llvmbuild_source_root",
8201e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help=(
8211e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar            "If given, an alternate path to search for LLVMBuild.txt files"),
8221e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None, metavar="PATH")
823b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    group.add_option("", "--build-root", dest="build_root", metavar="PATH",
824b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      help="Path to the build directory (if needed) [%default]",
825b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      action="store", default=None)
8261e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
8271e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
8281e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group = OptionGroup(parser, "Output Options")
8291e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--print-tree", dest="print_tree",
8301e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Print out the project component tree [%default]",
8311e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store_true", default=False)
8321e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-llvmbuild", dest="write_llvmbuild",
83343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                      help="Write out the LLVMBuild.txt files to PATH",
83443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar                      action="store", default=None, metavar="PATH")
8351e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-library-table",
8361e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="write_library_table", metavar="PATH",
8371e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the C++ library dependency table to PATH",
8381e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
8391e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-cmake-fragment",
8401e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     dest="write_cmake_fragment", metavar="PATH",
8411e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the CMake project information to PATH",
8421e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    group.add_option("", "--write-cmake-exports-fragment",
84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     dest="write_cmake_exports_fragment", metavar="PATH",
84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     help="Write the CMake exports information to PATH",
84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     action="store", default=None)
8471e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    group.add_option("", "--write-make-fragment",
84802271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                      dest="write_make_fragment", metavar="PATH",
8491e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     help="Write the Makefile project information to PATH",
8501e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar                     action="store", default=None)
851b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    group.add_option("", "--configure-target-def-file",
852b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     dest="configure_target_def_files",
853b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     help="""Configure the given file at SUBPATH (relative to
854b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarthe inferred or given source root, and with a '.in' suffix) by replacing certain
855b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarsubstitution variables with lists of targets that support certain features (for
856b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbarexample, targets with AsmPrinters) and write the result to the build root (as
857b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbargiven by --build-root) at the same SUBPATH""",
858b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                     metavar="SUBPATH", action="append", default=None)
8591e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
860affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
861affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group = OptionGroup(parser, "Configuration Options")
862affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group.add_option("", "--native-target",
863affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      dest="native_target", metavar="NAME",
864affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      help=("Treat the named target as the 'native' one, if "
865affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                            "given [%default]"),
866affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      action="store", default=None)
867affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    group.add_option("", "--enable-targets",
868affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar                      dest="enable_targets", metavar="NAMES",
86983337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar                      help=("Enable the given space or semi-colon separated "
87083337302595a6b85523be8522c2b6105c8e159d1Daniel Dunbar                            "list of targets, or all targets if not present"),
87102271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar                      action="store", default=None)
872754935418133ece1f51d1857a61d538797c34891Preston Gurd    group.add_option("", "--enable-optional-components",
873754935418133ece1f51d1857a61d538797c34891Preston Gurd                      dest="optional_components", metavar="NAMES",
874754935418133ece1f51d1857a61d538797c34891Preston Gurd                      help=("Enable the given space or semi-colon separated "
875754935418133ece1f51d1857a61d538797c34891Preston Gurd                            "list of optional components"),
876b49fb7bcd5001567d2da06f6a6e1c7ba79649e1bDaniel Dunbar                      action="store", default="")
8771e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar    parser.add_option_group(group)
8781e5b24330b11fb2631c7bc2892ba6364309fe385Daniel Dunbar
879ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    (opts, args) = parser.parse_args()
880ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
881ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    # Determine the LLVM source path, if not given.
882ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    source_root = opts.source_root
883ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    if source_root:
884c2c50cdcdc19a1bca993c06d13d8cdca87083ce4Chandler Carruth        if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
885ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                                           'Function.cpp')):
886ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar            parser.error('invalid LLVM source root: %r' % source_root)
887ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    else:
888ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        llvmbuild_path = os.path.dirname(__file__)
889ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        llvm_build_path = os.path.dirname(llvmbuild_path)
890ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        utils_path = os.path.dirname(llvm_build_path)
891ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar        source_root = os.path.dirname(utils_path)
892c2c50cdcdc19a1bca993c06d13d8cdca87083ce4Chandler Carruth        if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
893ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar                                           'Function.cpp')):
894ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar            parser.error('unable to infer LLVM source root, please specify')
895ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar
896df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    # Construct the LLVM project information.
897df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    llvmbuild_source_root = opts.llvmbuild_source_root or source_root
898df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar    project_info = LLVMProjectInfo.load_from_path(
899df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar        source_root, llvmbuild_source_root)
900df578254a1241a6cab122aa6d5396995d928e24aDaniel Dunbar
901affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    # Add the magic target based components.
902affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar    add_magic_target_components(parser, project_info, opts)
903affc6cf9d2b2b74532ce82027ac4524d1e29a658Daniel Dunbar
904b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    # Validate the project component info.
905b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar    project_info.validate_components()
906b4eaee7a4407a73d95b042b08523e9ace577e2a1Daniel Dunbar
90700b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    # Print the component tree, if requested.
90800b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar    if opts.print_tree:
90900b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar        project_info.print_tree()
91000b4b4f5cb95b5984174ac8086dcf878e2fa24e4Daniel Dunbar
91143120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    # Write out the components, if requested. This is useful for auto-upgrading
91243120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    # the schema.
91343120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar    if opts.write_llvmbuild:
91443120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar        project_info.write_components(opts.write_llvmbuild)
91543120df44b629cc1ef0b587007bec5c31fb799a1Daniel Dunbar
9161688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the required library table, if requested.
917efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar    if opts.write_library_table:
918754935418133ece1f51d1857a61d538797c34891Preston Gurd        project_info.write_library_table(opts.write_library_table,
919754935418133ece1f51d1857a61d538797c34891Preston Gurd                                         opts.optional_components)
920efe2f644ec15913aa84460bb7ac97b8fa6164b3fDaniel Dunbar
9211688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the make fragment, if requested.
92202271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar    if opts.write_make_fragment:
92302271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar        project_info.write_make_fragment(opts.write_make_fragment)
92402271a7b42ab658115c19d5041eaed2001b9537cDaniel Dunbar
9251688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    # Write out the cmake fragment, if requested.
9261688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar    if opts.write_cmake_fragment:
92737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        project_info.write_cmake_fragment(opts.write_cmake_fragment,
92837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                          opts.optional_components)
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if opts.write_cmake_exports_fragment:
93037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment,
93137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  opts.optional_components)
9321688961d4e148638f42c19b8d5ede48c63e28510Daniel Dunbar
933b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    # Configure target definition files, if requested.
934b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar    if opts.configure_target_def_files:
935b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Verify we were given a build root.
936b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        if not opts.build_root:
937b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            parser.error("must specify --build-root when using "
938b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                         "--configure-target-def-file")
939b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
940b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Create the substitution list.
941b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        available_targets = [ci for ci in project_info.component_infos
942b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                             if ci.type_name == 'TargetGroup']
943b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        substitutions = [
944b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_TARGETS@",
945b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_TARGET(%s)' % ci.name
946b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets)),
947b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_ASM_PRINTERS@",
948b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_ASM_PRINTER(%s)' % ci.name
949b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
950b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_asmprinter)),
951b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_ASM_PARSERS@",
952b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_ASM_PARSER(%s)' % ci.name
953b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
954b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_asmparser)),
955b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            ("@LLVM_ENUM_DISASSEMBLERS@",
956b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar             ' '.join('LLVM_DISASSEMBLER(%s)' % ci.name
957b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      for ci in available_targets
958b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                      if ci.has_disassembler))]
959b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
960b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        # Configure the given files.
961b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar        for subpath in opts.configure_target_def_files:
962b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            inpath = os.path.join(source_root, subpath + '.in')
963b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            outpath = os.path.join(opts.build_root, subpath)
964b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            result = configutil.configure_file(inpath, outpath, substitutions)
965b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar            if not result:
966b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar                note("configured file %r hasn't changed" % outpath)
967b7f3bfc559f1ed541f8293ebb519cfb898dc757aDaniel Dunbar
968ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbarif __name__=='__main__':
969ad5e0122c1e7f5d8a92cad7086a2f232748ba3ceDaniel Dunbar    main()
970