1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements.  See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership.  The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License.  You may obtain a copy of the License at
8#
9#   http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied.  See the License for the
15# specific language governing permissions and limitations
16# under the License.
17
18"""Defines an Artifact subclass that describes a compiled static library."""
19
20from tvm.contrib import util
21from . import artifact
22from . import compiler
23
24
25class MicroLibrary(artifact.Artifact):
26    """An Artifact that describes a compiled static library."""
27
28    ARTIFACT_TYPE = "micro_library"
29
30    @classmethod
31    def from_unarchived(cls, base_dir, labelled_files, metadata):
32        library_files = labelled_files["library_files"]
33        del labelled_files["library_files"]
34
35        debug_files = None
36        if "debug_files" in labelled_files:
37            debug_files = labelled_files["debug_files"]
38            del labelled_files["debug_files"]
39
40        return cls(
41            base_dir,
42            library_files,
43            debug_files=debug_files,
44            labelled_files=labelled_files,
45            metadata=metadata,
46        )
47
48    def __init__(
49        self, base_dir, library_files, debug_files=None, labelled_files=None, metadata=None
50    ):
51        labelled_files = {} if labelled_files is None else dict(labelled_files)
52        metadata = {} if metadata is None else dict(metadata)
53        labelled_files["library_files"] = library_files
54        if debug_files is not None:
55            labelled_files["debug_files"] = debug_files
56
57        super(MicroLibrary, self).__init__(base_dir, labelled_files, metadata)
58
59        self.library_files = library_files
60        self.debug_file = debug_files
61
62
63def create_micro_library(output, objects, options=None):
64    """Create a MicroLibrary using the default compiler options.
65
66    Parameters
67    ----------
68    output : str
69      Path to the output file, expected to end in .tar.
70    objects : List[str]
71      Paths to the source files to include in the library.
72    options : Optional[List[str]]
73      If given, additional command-line flags for the compiler.
74    """
75    temp_dir = util.tempdir()
76    comp = compiler.DefaultCompiler()
77    output = temp_dir.relpath("micro-library.o")
78    comp.library(output, objects, options=options)
79
80    with open(output, "rb") as output_f:
81        elf_data = output_f.read()
82
83    # TODO(areusch): Define a mechanism to determine compiler and linker flags for each lib
84    # enabled by the target str, and embed here.
85    micro_lib = MicroLibrary("", elf_data, {"target": comp.target.str()})
86    micro_lib.save(output)
87