Support auxiliary files with dynamic content from the file system.

Sometimes, auxiliary file content comes from another file, rather than
being defined entirely in code. In that case, delay reading the file to
the execution phase in order to let executors handle that as required.
This commit is contained in:
Grant Paul 2016-07-18 00:08:13 -07:00
parent b24894a8e0
commit 26e2bc9512
8 changed files with 51 additions and 26 deletions

View File

@ -20,20 +20,23 @@ class Invocation {
public:
class AuxiliaryFile {
private:
std::string _path;
std::vector<uint8_t> _contents;
bool _executable;
std::string _path;
ext::optional<std::vector<uint8_t>> _contentsData;
ext::optional<std::string> _contentsPath;
bool _executable;
public:
AuxiliaryFile(std::string const &path, std::vector<uint8_t> const &contents, bool executable);
AuxiliaryFile(std::string const &path, std::string const &contents, bool executable);
AuxiliaryFile(std::string const &path, std::vector<uint8_t> const &contentsData, bool executable);
AuxiliaryFile(std::string const &path, std::string const &contentsPath, bool executable);
~AuxiliaryFile();
public:
std::string const &path() const
{ return _path; }
std::vector<uint8_t> const &contents() const
{ return _contents; }
ext::optional<std::vector<uint8_t>> const &contentsData() const
{ return _contentsData; }
ext::optional<std::string> const &contentsPath() const
{ return _contentsPath; }
bool executable() const
{ return _executable; }
};

View File

@ -38,7 +38,7 @@ public:
public:
std::string hash() const;
std::string serialize() const;
std::vector<uint8_t> serialize() const;
public:
pbxsetting::Value logicalOutputPath() const;

View File

@ -21,18 +21,18 @@ using libutil::FSUtil;
using libutil::SysUtil;
AuxiliaryFile::
AuxiliaryFile(std::string const &path, std::vector<uint8_t> const &contents, bool executable) :
_path (path),
_contents (contents),
_executable(executable)
AuxiliaryFile(std::string const &path, std::vector<uint8_t> const &contentsData, bool executable) :
_path (path),
_contentsData(contentsData),
_executable (executable)
{
}
AuxiliaryFile::
AuxiliaryFile(std::string const &path, std::string const &contents, bool executable) :
_path (path),
_contents (std::vector<uint8_t>(contents.begin(), contents.end())),
_executable(executable)
AuxiliaryFile(std::string const &path, std::string const &contentsPath, bool executable) :
_path (path),
_contentsPath(contentsPath),
_executable (executable)
{
}

View File

@ -49,7 +49,7 @@ resolve(
for (std::string const &input : inputFiles) {
contents += input + "\n";
}
Tool::Invocation::AuxiliaryFile fileList = Tool::Invocation::AuxiliaryFile(path, contents, false);
Tool::Invocation::AuxiliaryFile fileList = Tool::Invocation::AuxiliaryFile(path, std::vector<uint8_t>(contents.begin(), contents.end()), false);
auxiliaries.push_back(fileList);
}

View File

@ -56,7 +56,7 @@ std::string Tool::PrecompiledHeaderInfo::
hash() const
{
// TODO(grp): Generate this hash properly.
std::string content = serialize();
std::vector<uint8_t> content = serialize();
md5_state_t state;
md5_init(&state);
@ -72,7 +72,7 @@ hash() const
return ss.str();
}
std::string Tool::PrecompiledHeaderInfo::
std::vector<uint8_t> Tool::PrecompiledHeaderInfo::
serialize() const
{
std::string result;
@ -86,7 +86,7 @@ serialize() const
result += "SDK_PRODUCT_BUILD_VERSION=FIXME\n";
result += "FIXME\n";
return result;
return std::vector<uint8_t>(result.begin(), result.end());
}
Tool::PrecompiledHeaderInfo Tool::PrecompiledHeaderInfo::

View File

@ -108,7 +108,7 @@ resolve(
std::string scriptFilePath = phaseEnvironment.expand(scriptPath);
std::string contents = (!buildPhase->shellPath().empty() ? "#!" + buildPhase->shellPath() + "\n" : "") + buildPhase->shellScript();
Tool::Invocation::AuxiliaryFile scriptFile = Tool::Invocation::AuxiliaryFile(scriptFilePath, contents, true);
Tool::Invocation::AuxiliaryFile scriptFile = Tool::Invocation::AuxiliaryFile(scriptFilePath, std::vector<uint8_t>(contents.begin(), contents.end()), true);
pbxsetting::Environment scriptEnvironment = environment;
scriptEnvironment.insertFront(ScriptInputOutputLevel(inputFiles, outputFiles, true), false);

View File

@ -614,9 +614,21 @@ buildTargetAuxiliaryFiles(
return false;
}
if (!filesystem->write(auxiliaryFile.contents(), auxiliaryFile.path())) {
fprintf(stderr, "error: failed to write auxiliary file: %s\n", auxiliaryFile.path().c_str());
return false;
if (auxiliaryFile.contentsData()) {
if (!filesystem->write(*auxiliaryFile.contentsData(), auxiliaryFile.path())) {
fprintf(stderr, "error: failed to write auxiliary file: %s\n", auxiliaryFile.path().c_str());
return false;
}
} else if (auxiliaryFile.contentsPath()) {
std::vector<uint8_t> contents;
if (!filesystem->read(&contents, *auxiliaryFile.contentsPath())) {
fprintf(stderr, "error: failed to read auxiliary file contents: %s\n", auxiliaryFile.contentsPath()->c_str());
return false;
}
if (!filesystem->write(contents, auxiliaryFile.path())) {
fprintf(stderr, "error: failed to write auxiliary file: %s\n", auxiliaryFile.path().c_str());
return false;
}
}
if (auxiliaryFile.executable() && !filesystem->isExecutable(auxiliaryFile.path())) {

View File

@ -167,8 +167,18 @@ writeAuxiliaryFiles(
xcformatter::Formatter::Print(_formatter->writeAuxiliaryFile(auxiliaryFile.path()));
if (!_dryRun) {
if (!filesystem->write(auxiliaryFile.contents(), auxiliaryFile.path())) {
return false;
if (auxiliaryFile.contentsData()) {
if (!filesystem->write(*auxiliaryFile.contentsData(), auxiliaryFile.path())) {
return false;
}
} else if (auxiliaryFile.contentsPath()) {
std::vector<uint8_t> contents;
if (!filesystem->read(&contents, *auxiliaryFile.contentsPath())) {
return false;
}
if (!filesystem->write(contents, auxiliaryFile.path())) {
return false;
}
}
}