Files
paddlepaddle--paddle/paddle/ap/include/code_module/project_compile_helper.h
T
2026-07-13 12:40:42 +08:00

131 lines
4.8 KiB
C++

// Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <sys/wait.h>
#include <fstream>
#include "paddle/ap/include/adt/adt.h"
#include "paddle/ap/include/code_module/project.h"
#include "paddle/ap/include/env/ap_path.h"
namespace ap::code_module {
struct ProjectCompileHelper {
ProjectCompileHelper(const std::string& workspace_dir_val,
const Project& project_val)
: workspace_dir(workspace_dir_val), project(project_val) {}
adt::Result<adt::Ok> DumpNestedFilesToFs() {
return DumpNestedFilesToFs(this->project->nested_files, "");
}
adt::Result<adt::Ok> Compile() {
int ret_code = 0;
std::string change_dir_cmd = std::string() + "cd " + this->workspace_dir;
std::string compile_cmd =
change_dir_cmd + "; " + this->project->compile_cmd;
ret_code = WEXITSTATUS(std::system(compile_cmd.c_str()));
ADT_CHECK(ret_code == 0) << adt::errors::RuntimeError{
std::string() + "system() failed. ret_code: " +
std::to_string(ret_code) + ", compile_cmd: " + compile_cmd};
return adt::Ok{};
}
std::string GetSoPath() {
return this->workspace_dir + "/" + this->project->so_relative_path;
}
private:
std::string workspace_dir;
Project project;
adt::Result<adt::Ok> DumpNestedFilesToFs(
const Directory<File>& directory, const std::string& relative_dir_path) {
std::string dir_path = this->workspace_dir + "/" + relative_dir_path;
std::string cmd = std::string() + "mkdir -p " + dir_path;
int ret = std::system(cmd.c_str());
ADT_CHECK(ret != -1 && WIFEXITED(ret) && WEXITSTATUS(ret) == 0)
<< adt::errors::RuntimeError{std::string() +
"mkdir failed. dir_path: " + dir_path +
", system return: " + std::to_string(ret)};
using Ok = adt::Result<adt::Ok>;
for (const auto& [dentry, file] : directory.dentry2file->storage) {
ADT_RETURN_IF_ERR(file.Match(
[&](const FileContent& file_content) -> Ok {
return DumpFileContentToFs(file_content,
relative_dir_path + "/" + dentry);
},
[&](const SoftLink& soft_link) -> Ok {
return DumpSoftLinkToFs(soft_link,
relative_dir_path + "/" + dentry);
},
[&](const Directory<File>& sub_dir) -> Ok {
return DumpNestedFilesToFs(sub_dir,
relative_dir_path + "/" + dentry);
}));
}
return adt::Ok{};
}
adt::Result<adt::Ok> DumpFileContentToFs(
const FileContent& file_content, const std::string& relative_file_path) {
std::string file_path = this->workspace_dir + "/" + relative_file_path;
std::ofstream of{file_path};
ADT_CHECK(of.is_open()) << adt::errors::RuntimeError{
std::string() + "file open failed. file_path: " + file_path};
of << file_content->file_content;
of.close();
return adt::Ok{};
}
adt::Result<adt::Ok> DumpSoftLinkToFs(const SoftLink& soft_link,
const std::string& relative_link_path) {
std::string link = this->workspace_dir + "/" + relative_link_path;
std::optional<std::string> target_path;
auto FindExistedSourcePath =
[&](const auto& prefix) -> adt::Result<adt::LoopCtrl> {
std::string cur_target_path =
std::string() + prefix + "/" + soft_link->target_relative_path;
if (FileExists(cur_target_path)) {
target_path = cur_target_path;
return adt::Break{};
} else {
return adt::Continue{};
}
};
ADT_RETURN_IF_ERR(env::VisitEachApPath(FindExistedSourcePath));
ADT_CHECK(target_path.has_value()) << adt::errors::RuntimeError{
std::string() +
"link failed. relative_path: " + soft_link->target_relative_path};
std::string cmd =
std::string() + "ln -s " + target_path.value() + " " + link;
ADT_CHECK(WEXITSTATUS(std::system(cmd.c_str())) == 0);
return adt::Ok{};
}
bool FileExists(const std::string& filepath) {
std::fstream fp;
fp.open(filepath, std::fstream::in);
if (fp.is_open()) {
fp.close();
return true;
} else {
return false;
}
}
};
} // namespace ap::code_module