16d528ed9Sopenharmony_ci// Copyright 2020 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci// found in the LICENSE file. 46d528ed9Sopenharmony_ci 56d528ed9Sopenharmony_ci#ifndef TOOLS_GN_RUST_PROJECT_WRITER_HELPERS_H_ 66d528ed9Sopenharmony_ci#define TOOLS_GN_RUST_PROJECT_WRITER_HELPERS_H_ 76d528ed9Sopenharmony_ci 86d528ed9Sopenharmony_ci#include <fstream> 96d528ed9Sopenharmony_ci#include <optional> 106d528ed9Sopenharmony_ci#include <sstream> 116d528ed9Sopenharmony_ci#include <string> 126d528ed9Sopenharmony_ci#include <string_view> 136d528ed9Sopenharmony_ci#include <tuple> 146d528ed9Sopenharmony_ci#include <unordered_map> 156d528ed9Sopenharmony_ci#include <vector> 166d528ed9Sopenharmony_ci 176d528ed9Sopenharmony_ci#include "base/containers/flat_map.h" 186d528ed9Sopenharmony_ci#include "build_settings.h" 196d528ed9Sopenharmony_ci#include "gn/source_file.h" 206d528ed9Sopenharmony_ci#include "gn/target.h" 216d528ed9Sopenharmony_ci 226d528ed9Sopenharmony_ci// These are internal types and helper functions for RustProjectWriter that have 236d528ed9Sopenharmony_ci// been extracted for easier testability. 246d528ed9Sopenharmony_ci 256d528ed9Sopenharmony_ci// Crate Index in the generated file 266d528ed9Sopenharmony_ciusing CrateIndex = size_t; 276d528ed9Sopenharmony_ci 286d528ed9Sopenharmony_ciusing ConfigList = std::vector<std::string>; 296d528ed9Sopenharmony_ciusing Dependency = std::pair<CrateIndex, std::string>; 306d528ed9Sopenharmony_ciusing DependencyList = std::vector<Dependency>; 316d528ed9Sopenharmony_ci 326d528ed9Sopenharmony_ci// This class represents a crate to be serialized out as part of the 336d528ed9Sopenharmony_ci// rust-project.json file. This is used to separate the generating 346d528ed9Sopenharmony_ci// of the data that needs to be in the file, from the file itself. 356d528ed9Sopenharmony_ciclass Crate { 366d528ed9Sopenharmony_ci public: 376d528ed9Sopenharmony_ci Crate(SourceFile root, 386d528ed9Sopenharmony_ci std::optional<OutputFile> gen_dir, 396d528ed9Sopenharmony_ci CrateIndex index, 406d528ed9Sopenharmony_ci std::string label, 416d528ed9Sopenharmony_ci std::string edition) 426d528ed9Sopenharmony_ci : root_(root), 436d528ed9Sopenharmony_ci gen_dir_(gen_dir), 446d528ed9Sopenharmony_ci index_(index), 456d528ed9Sopenharmony_ci label_(label), 466d528ed9Sopenharmony_ci edition_(edition) {} 476d528ed9Sopenharmony_ci 486d528ed9Sopenharmony_ci ~Crate() = default; 496d528ed9Sopenharmony_ci 506d528ed9Sopenharmony_ci // Add a config item to the crate. 516d528ed9Sopenharmony_ci void AddConfigItem(std::string cfg_item) { configs_.push_back(cfg_item); } 526d528ed9Sopenharmony_ci 536d528ed9Sopenharmony_ci // Add a key-value environment variable pair used when building this crate. 546d528ed9Sopenharmony_ci void AddRustenv(std::string key, std::string value) { 556d528ed9Sopenharmony_ci rustenv_.emplace(key, value); 566d528ed9Sopenharmony_ci } 576d528ed9Sopenharmony_ci 586d528ed9Sopenharmony_ci // Add another crate as a dependency of this one. 596d528ed9Sopenharmony_ci void AddDependency(CrateIndex index, std::string name) { 606d528ed9Sopenharmony_ci deps_.push_back(std::make_pair(index, name)); 616d528ed9Sopenharmony_ci } 626d528ed9Sopenharmony_ci 636d528ed9Sopenharmony_ci // Set the compiler arguments used to invoke the compilation of this crate 646d528ed9Sopenharmony_ci void SetCompilerArgs(std::vector<std::string> args) { compiler_args_ = args; } 656d528ed9Sopenharmony_ci 666d528ed9Sopenharmony_ci // Set the compiler target ("e.g. x86_64-linux-kernel") 676d528ed9Sopenharmony_ci void SetCompilerTarget(std::string target) { compiler_target_ = target; } 686d528ed9Sopenharmony_ci 696d528ed9Sopenharmony_ci // Set that this is a proc macro with the path to the output .so/dylib/dll 706d528ed9Sopenharmony_ci void SetIsProcMacro(OutputFile proc_macro_dynamic_library) { 716d528ed9Sopenharmony_ci proc_macro_dynamic_library_ = proc_macro_dynamic_library; 726d528ed9Sopenharmony_ci } 736d528ed9Sopenharmony_ci 746d528ed9Sopenharmony_ci // Returns the root file for the crate. 756d528ed9Sopenharmony_ci SourceFile& root() { return root_; } 766d528ed9Sopenharmony_ci 776d528ed9Sopenharmony_ci // Returns the root file for the crate. 786d528ed9Sopenharmony_ci std::optional<OutputFile>& gen_dir() { return gen_dir_; } 796d528ed9Sopenharmony_ci 806d528ed9Sopenharmony_ci // Returns the crate index. 816d528ed9Sopenharmony_ci CrateIndex index() { return index_; } 826d528ed9Sopenharmony_ci 836d528ed9Sopenharmony_ci // Returns the displayable crate label. 846d528ed9Sopenharmony_ci const std::string& label() { return label_; } 856d528ed9Sopenharmony_ci 866d528ed9Sopenharmony_ci // Returns the Rust Edition this crate uses. 876d528ed9Sopenharmony_ci const std::string& edition() { return edition_; } 886d528ed9Sopenharmony_ci 896d528ed9Sopenharmony_ci // Return the set of config items for this crate. 906d528ed9Sopenharmony_ci ConfigList& configs() { return configs_; } 916d528ed9Sopenharmony_ci 926d528ed9Sopenharmony_ci // Return the set of dependencies for this crate. 936d528ed9Sopenharmony_ci DependencyList& dependencies() { return deps_; } 946d528ed9Sopenharmony_ci 956d528ed9Sopenharmony_ci // Return the compiler arguments used to invoke the compilation of this crate 966d528ed9Sopenharmony_ci const std::vector<std::string>& CompilerArgs() { return compiler_args_; } 976d528ed9Sopenharmony_ci 986d528ed9Sopenharmony_ci // Return the compiler target "triple" from the compiler args 996d528ed9Sopenharmony_ci const std::optional<std::string>& CompilerTarget() { 1006d528ed9Sopenharmony_ci return compiler_target_; 1016d528ed9Sopenharmony_ci } 1026d528ed9Sopenharmony_ci 1036d528ed9Sopenharmony_ci // Returns whether this crate builds a proc macro .so 1046d528ed9Sopenharmony_ci const std::optional<OutputFile>& proc_macro_path() { 1056d528ed9Sopenharmony_ci return proc_macro_dynamic_library_; 1066d528ed9Sopenharmony_ci } 1076d528ed9Sopenharmony_ci 1086d528ed9Sopenharmony_ci // Returns environment variables applied to this, which may be necessary 1096d528ed9Sopenharmony_ci // for correct functioning of environment variables 1106d528ed9Sopenharmony_ci const base::flat_map<std::string, std::string>& rustenv() { return rustenv_; } 1116d528ed9Sopenharmony_ci 1126d528ed9Sopenharmony_ci private: 1136d528ed9Sopenharmony_ci SourceFile root_; 1146d528ed9Sopenharmony_ci std::optional<OutputFile> gen_dir_; 1156d528ed9Sopenharmony_ci CrateIndex index_; 1166d528ed9Sopenharmony_ci std::string label_; 1176d528ed9Sopenharmony_ci std::string edition_; 1186d528ed9Sopenharmony_ci ConfigList configs_; 1196d528ed9Sopenharmony_ci DependencyList deps_; 1206d528ed9Sopenharmony_ci std::optional<std::string> compiler_target_; 1216d528ed9Sopenharmony_ci std::vector<std::string> compiler_args_; 1226d528ed9Sopenharmony_ci std::optional<OutputFile> proc_macro_dynamic_library_; 1236d528ed9Sopenharmony_ci base::flat_map<std::string, std::string> rustenv_; 1246d528ed9Sopenharmony_ci}; 1256d528ed9Sopenharmony_ci 1266d528ed9Sopenharmony_ciusing CrateList = std::vector<Crate>; 1276d528ed9Sopenharmony_ci 1286d528ed9Sopenharmony_ci// Write the entire rust-project.json file contents into the given stream, based 1296d528ed9Sopenharmony_ci// on the the given crates list. 1306d528ed9Sopenharmony_civoid WriteCrates(const BuildSettings* build_settings, 1316d528ed9Sopenharmony_ci CrateList& crate_list, 1326d528ed9Sopenharmony_ci std::optional<std::string>& sysroot, 1336d528ed9Sopenharmony_ci std::ostream& rust_project); 1346d528ed9Sopenharmony_ci 1356d528ed9Sopenharmony_ci// Assemble the compiler arguments for the given GN Target. 1366d528ed9Sopenharmony_cistd::vector<std::string> ExtractCompilerArgs(const Target* target); 1376d528ed9Sopenharmony_ci 1386d528ed9Sopenharmony_ci// Find the value of an argument that's passed to the compiler as two 1396d528ed9Sopenharmony_ci// consecutive strings in the list of arguments: ["arg", "value"] 1406d528ed9Sopenharmony_cistd::optional<std::string> FindArgValue(const char* arg, 1416d528ed9Sopenharmony_ci const std::vector<std::string>& args); 1426d528ed9Sopenharmony_ci 1436d528ed9Sopenharmony_ci// Find the first argument that matches the prefix, returning the value after 1446d528ed9Sopenharmony_ci// the prefix. e.g. ˝--arg=value", is returned as "value" if the prefix 1456d528ed9Sopenharmony_ci// "--arg=" is used. 1466d528ed9Sopenharmony_cistd::optional<std::string> FindArgValueAfterPrefix( 1476d528ed9Sopenharmony_ci const std::string& prefix, 1486d528ed9Sopenharmony_ci const std::vector<std::string>& args); 1496d528ed9Sopenharmony_ci 1506d528ed9Sopenharmony_ci// Find all arguments that match the given prefix, returning the value after 1516d528ed9Sopenharmony_ci// the prefix for each one. e.g. "--cfg=value" is returned as "value" if the 1526d528ed9Sopenharmony_ci// prefix "--cfg=" is used. 1536d528ed9Sopenharmony_cistd::vector<std::string> FindAllArgValuesAfterPrefix( 1546d528ed9Sopenharmony_ci const std::string& prefix, 1556d528ed9Sopenharmony_ci const std::vector<std::string>& args); 1566d528ed9Sopenharmony_ci 1576d528ed9Sopenharmony_ci#endif // TOOLS_GN_RUST_PROJECT_WRITER_HELPERS_H_ 158