5 // Created by Louis Gerbarg on 7/23/15.
17 #include <unordered_map>
18 #include <unordered_set>
24 extern void terminate(const char* format
, ...) __printflike(1, 2) __attribute__((noreturn
));
25 extern std::string
toolDir();
32 std::vector
<std::string
> sources
;
38 File( MachOProxy
* P
) : proxy( P
) {}
42 ImageIdentifier identifier
;
44 Anchor( const ImageIdentifier
& I
) : identifier( I
) {}
53 struct SegmentInfoHasher
{
54 std::size_t operator()(const SegmentInfo
&x
) const {
55 return std::hash
<std::string
>()(x
.name
) ^ std::hash
<uint64_t>()(x
.startAddr
) ^ std::hash
<uint64_t>()(x
.endAddr
);
60 std::vector
<SegmentInfo
> regions
;
66 std::string exclusionInfo
;
68 std::string installname
;
69 std::vector
<SegmentInfo
> segments
;
70 DylibInfo(void) : included(true) {}
75 std::map
<ImageIdentifier
, DylibInfo
> dylibs
;
76 std::vector
<std::string
> warnings
;
77 CacheInfo developmentCache
;
78 CacheInfo productionCache
;
79 DylibInfo
& dylibForInstallname(const std::string
& installname
)
81 auto i
= find_if(dylibs
.begin(), dylibs
.end(), [&installname
](std::pair
<ImageIdentifier
, DylibInfo
> d
) { return d
.second
.installname
== installname
; });
82 assert(i
!= dylibs
.end());
85 void exclude(MachOProxy
* proxy
, const std::string
& reason
);
89 std::vector
<Anchor
> anchors
;
90 mutable Results results
;
92 bool operator==(const Architecture
& O
) const
94 for (auto& dylib
: results
.dylibs
) {
95 if (dylib
.second
.included
) {
96 auto Odylib
= O
.results
.dylibs
.find(dylib
.first
);
97 if (Odylib
== O
.results
.dylibs
.end()
98 || Odylib
->second
.included
== false
99 || Odylib
->second
.uuid
!= dylib
.second
.uuid
)
104 for (const auto& Odylib
: O
.results
.dylibs
) {
105 if (Odylib
.second
.included
) {
106 auto dylib
= results
.dylibs
.find(Odylib
.first
);
107 if (dylib
== results
.dylibs
.end()
108 || dylib
->second
.included
== false
109 || dylib
->second
.uuid
!= Odylib
.second
.uuid
)
117 bool operator!=(const Architecture
& other
) const { return !(*this == other
); }
120 struct Configuration
{
121 std::string platformName
;
122 std::string metabomTag
;
123 std::set
<std::string
> metabomExcludeTags
;
124 std::set
<std::string
> metabomRestrictTags
;
125 std::set
<std::string
> restrictedInstallnames
;
126 std::map
<std::string
, Architecture
> architectures
;
128 bool operator==(const Configuration
& O
) const
130 return architectures
== O
.architectures
;
133 bool operator!=(const Configuration
& other
) const { return !(*this == other
); }
135 const Architecture
& architecture(const std::string
& architecture
) const
137 assert(architectures
.find(architecture
) != architectures
.end());
138 return architectures
.find(architecture
)->second
;
141 void forEachArchitecture(std::function
<void(const std::string
& archName
)> lambda
)
143 for (const auto& architecutre
: architectures
) {
144 lambda(architecutre
.first
);
149 const std::map
<std::string
, Project
>& projects()
154 const Configuration
& configuration(const std::string
& configuration
) const
156 assert(_configurations
.find(configuration
) != _configurations
.end());
157 return _configurations
.find(configuration
)->second
;
160 void forEachConfiguration(std::function
<void(const std::string
& configName
)> lambda
)
162 for (const auto& configuration
: _configurations
) {
163 lambda(configuration
.first
);
167 void addProjectSource(const std::string
& project
, const std::string
& source
, bool first
= false)
169 auto& sources
= _projects
[project
].sources
;
170 if (std::find(sources
.begin(), sources
.end(), source
) == sources
.end()) {
172 sources
.insert(sources
.begin(), source
);
174 sources
.push_back(source
);
179 const std::string
projectPath(const std::string
& projectName
)
181 auto project
= _projects
.find(projectName
);
182 if (project
== _projects
.end())
184 if (project
->second
.sources
.size() == 0)
186 return project
->second
.sources
[0];
190 const bool empty(void) {
191 for (const auto& configuration
: _configurations
) {
192 if (configuration
.second
.architectures
.size() != 0)
198 const std::string
dylibOrderFile() const { return _dylibOrderFile
; };
199 void setDylibOrderFile(const std::string
& dylibOrderFile
) { _dylibOrderFile
= dylibOrderFile
; };
201 const std::string
dirtyDataOrderFile() const { return _dirtyDataOrderFile
; };
202 void setDirtyDataOrderFile(const std::string
& dirtyDataOrderFile
) { _dirtyDataOrderFile
= dirtyDataOrderFile
; };
204 const std::string
metabomFile() const { return _metabomFile
; };
205 void setMetabomFile(const std::string
& metabomFile
) { _metabomFile
= metabomFile
; };
207 const std::string
platform() const { return _platform
; };
208 void setPlatform(const std::string
& platform
) { _platform
= platform
; };
210 const std::string
& build() const { return _build
; };
211 void setBuild(const std::string
& build
) { _build
= build
; };
212 const uint32_t version() const { return _manifestVersion
; };
213 void setVersion(const uint32_t manifestVersion
) { _manifestVersion
= manifestVersion
; };
217 Manifest(const std::set
<std::string
>& archs
, const std::string
& overlayPath
, const std::string
& rootPath
, const std::set
<std::string
>& paths
);
219 Manifest(const std::string
& path
);
220 Manifest(const std::string
& path
, const std::set
<std::string
>& overlays
);
222 void write(const std::string
& path
);
223 void canonicalize(void);
224 void calculateClosure(bool enforeceRootless
);
225 bool sameContentsAsCacheAtPath(const std::string
& configuration
, const std::string
& architecture
,
226 const std::string
& path
) const;
227 void remove(const std::string
& config
, const std::string
& arch
);
228 MachOProxy
* removeLargestLeafDylib(const std::string
& configuration
, const std::string
& architecture
);
230 void runConcurrently(dispatch_queue_t queue
, dispatch_semaphore_t concurrencyLimitingSemaphore
, std::function
<void(const std::string configuration
, const std::string architecture
)> lambda
);
231 bool filterForConfig(const std::string
& configName
);
234 uint32_t _manifestVersion
;
236 std::string _dylibOrderFile
;
237 std::string _dirtyDataOrderFile
;
238 std::string _metabomFile
;
239 std::string _platform
;
240 std::map
<std::string
, Project
> _projects
;
241 std::map
<std::string
, Configuration
> _configurations
;
242 void removeDylib(MachOProxy
* proxy
, const std::string
& reason
, const std::string
& configuration
, const std::string
& architecture
,
243 std::unordered_set
<ImageIdentifier
>& processedIdentifiers
);
244 void calculateClosure(const std::string
& configuration
, const std::string
& architecture
);
245 void canonicalizeDylib(const std::string
& installname
);
246 template <typename P
>
247 void canonicalizeDylib(const std::string
& installname
, const uint8_t* p
);
248 void addImplicitAliases(void);
249 MachOProxy
* dylibProxy(const std::string
& installname
, const std::string
& arch
);
253 #endif /* Manifest_h */