void Tool::ScriptResolver::
resolve(
    Tool::Context *toolContext,
    pbxsetting::Environment const &environment,
    pbxproj::PBX::ShellScriptBuildPhase::shared_ptr const &buildPhase) const
{
    pbxsetting::Level level = pbxsetting::Level({
        pbxsetting::Setting::Create("BuildPhaseName", (!buildPhase->name().empty() ? buildPhase->name() : "Run Script")),
        pbxsetting::Setting::Create("BuildPhaseIdentifier", buildPhase->blueprintIdentifier()),
    });

    pbxsetting::Environment phaseEnvironment = environment;
    phaseEnvironment.insertFront(level, false);

    pbxsetting::Value scriptPath = pbxsetting::Value::Parse("$(TEMP_FILES_DIR)/Script-$(BuildPhaseIdentifier).sh");
    pbxsetting::Value logMessage = pbxsetting::Value::Parse("PhaseScriptExecution $(BuildPhaseName:quote) ") + scriptPath;

    std::vector<std::string> inputFiles;
    std::transform(buildPhase->inputPaths().begin(), buildPhase->inputPaths().end(), std::back_inserter(inputFiles), [&](pbxsetting::Value const &input) -> std::string {
        std::string path = environment.expand(input);
        return FSUtil::ResolveRelativePath(path, toolContext->workingDirectory());
    });

    std::vector<std::string> outputFiles;
    std::transform(buildPhase->outputPaths().begin(), buildPhase->outputPaths().end(), std::back_inserter(outputFiles), [&](pbxsetting::Value const &output) -> std::string {
        std::string path = environment.expand(output);
        return FSUtil::ResolveRelativePath(path, toolContext->workingDirectory());
    });

    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);

    pbxsetting::Environment scriptEnvironment = environment;
    scriptEnvironment.insertFront(ScriptInputOutputLevel(inputFiles, outputFiles, true), false);
    std::unordered_map<std::string, std::string> environmentVariables = scriptEnvironment.computeValues(pbxsetting::Condition::Empty());

    Tool::Invocation invocation;
    invocation.executable() = Tool::Invocation::Executable::Absolute("/bin/sh");
    invocation.arguments() = { "-c", Escape::Shell(scriptFilePath) };
    invocation.environment() = environmentVariables;
    invocation.workingDirectory() = toolContext->workingDirectory();
    invocation.phonyInputs() = inputFiles; /* User-specified, may not exist. */
    invocation.outputs() = outputFiles;
    invocation.auxiliaryFiles() = { scriptFile };
    invocation.logMessage() = phaseEnvironment.expand(logMessage);
    invocation.showEnvironmentInLog() = buildPhase->showEnvVarsInLog();
    toolContext->invocations().push_back(invocation);
}
Exemple #2
0
void Tool::SymlinkResolver::
resolve(
    Tool::Context *toolContext,
    std::string const &workingDirectory,
    std::string const &symlinkPath,
    std::string const &targetPath,
    bool productStructure) const
{
    std::string logMessage = "SymLink " + targetPath + " " + symlinkPath;

    Tool::Invocation invocation;
    invocation.executable() = Tool::Invocation::Executable::External("/bin/ln");
    invocation.arguments() = { "-sfh", targetPath, symlinkPath };
    invocation.workingDirectory() = workingDirectory;
    invocation.phonyInputs() = { FSUtil::ResolveRelativePath(targetPath, workingDirectory) };
    invocation.outputs() = { FSUtil::ResolveRelativePath(symlinkPath, workingDirectory) };
    invocation.logMessage() = logMessage;
    invocation.createsProductStructure() = productStructure;
    invocation.priority() = toolContext->currentPhaseInvocationPriority();
    toolContext->invocations().push_back(invocation);
}