diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
commit | 619def44c1cca9f3cdf63544d5f24f2c7a7d9b77 (patch) | |
tree | 01868de723cb82c86842f33743fa7b14e24c1fa3 /src/buildtool/build_engine/base_maps/source_map.cpp | |
download | justbuild-619def44c1cca9f3cdf63544d5f24f2c7a7d9b77.tar.gz |
Initial self-hosting commit
This is the initial version of our tool that is able to
build itself. In can be bootstrapped by
./bin/bootstrap.py
Co-authored-by: Oliver Reiche <oliver.reiche@huawei.com>
Co-authored-by: Victor Moreno <victor.moreno1@huawei.com>
Diffstat (limited to 'src/buildtool/build_engine/base_maps/source_map.cpp')
-rw-r--r-- | src/buildtool/build_engine/base_maps/source_map.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/buildtool/build_engine/base_maps/source_map.cpp b/src/buildtool/build_engine/base_maps/source_map.cpp new file mode 100644 index 00000000..5c2a79d0 --- /dev/null +++ b/src/buildtool/build_engine/base_maps/source_map.cpp @@ -0,0 +1,88 @@ +#include "src/buildtool/build_engine/base_maps/source_map.hpp" + +#include <filesystem> + +#include "src/buildtool/common/artifact_digest.hpp" +#include "src/buildtool/file_system/object_type.hpp" +#include "src/buildtool/multithreading/async_map_consumer.hpp" +#include "src/utils/cpp/json.hpp" + +namespace BuildMaps::Base { + +namespace { + +auto as_target(const BuildMaps::Base::EntityName& key, ExpressionPtr artifact) + -> AnalysedTargetPtr { + auto stage = + ExpressionPtr{Expression::map_t{key.name, std::move(artifact)}}; + return std::make_shared<AnalysedTarget>( + TargetResult{stage, Expression::kEmptyMap, stage}, + std::vector<ActionDescription>{}, + std::vector<std::string>{}, + std::vector<Tree>{}, + std::unordered_set<std::string>{}, + std::set<std::string>{}); +} + +} // namespace + +auto CreateSourceTargetMap(const gsl::not_null<DirectoryEntriesMap*>& dirs, + std::size_t jobs) -> SourceTargetMap { + auto src_target_reader = [dirs](auto ts, + auto setter, + auto logger, + auto /* unused */, + auto const& key) { + using std::filesystem::path; + auto name = path(key.name).lexically_normal(); + if (name.is_absolute() or *name.begin() == "..") { + (*logger)( + fmt::format("Source file reference outside current module: {}", + key.name), + true); + return; + } + auto dir = (path(key.module) / name).parent_path(); + auto const* ws_root = + RepositoryConfig::Instance().WorkspaceRoot(key.repository); + + auto src_file_reader = [ts, key, name, setter, logger, dir, ws_root]( + bool exists_in_ws_root) { + if (ws_root != nullptr and exists_in_ws_root) { + if (auto desc = ws_root->ToArtifactDescription( + path(key.module) / name, key.repository)) { + (*setter)(as_target(key, ExpressionPtr{std::move(*desc)})); + return; + } + } + (*logger)(fmt::format("Cannot determine source file {}", + path(key.name).filename().string()), + true); + }; + + if (ws_root != nullptr and ws_root->HasFastDirectoryLookup()) { + // by-pass directory map and directly attempt to read from ws_root + src_file_reader(ws_root->IsFile(path(key.module) / name)); + return; + } + dirs->ConsumeAfterKeysReady( + ts, + {ModuleName{key.repository, dir.string()}}, + [key, src_file_reader](auto values) { + src_file_reader( + values[0]->Contains(path(key.name).filename().string())); + }, + [logger, dir](auto msg, auto fatal) { + (*logger)( + fmt::format( + "While reading contents of {}: {}", dir.string(), msg), + fatal); + } + + ); + }; + return AsyncMapConsumer<EntityName, AnalysedTargetPtr>(src_target_reader, + jobs); +} + +}; // namespace BuildMaps::Base |