@@ -623,10 +623,59 @@ std::string canonical_package_build_metadata(
623623 s += " cxxflag:" ;
624624 s += flag;
625625 }
626+ for (auto const & [path, content] : pkg.manifest .buildConfig .generatedFiles ) {
627+ s += " genfile:" ;
628+ s += path.generic_string ();
629+ s += " =" ;
630+ s += content;
631+ }
626632 }
627633 return s;
628634}
629635
636+ std::expected<void , std::string>
637+ materialize_generated_files (const std::filesystem::path& root,
638+ const mcpp::manifest::Manifest& manifest)
639+ {
640+ for (auto const & [relPath, content] : manifest.buildConfig .generatedFiles ) {
641+ if (relPath.empty ()) {
642+ return std::unexpected (" generated_files contains an empty path" );
643+ }
644+ if (relPath.is_absolute ()) {
645+ return std::unexpected (std::format (
646+ " generated_files path '{}' must be relative" , relPath.generic_string ()));
647+ }
648+ for (auto const & part : relPath) {
649+ if (part == " .." ) {
650+ return std::unexpected (std::format (
651+ " generated_files path '{}' must not escape the package root" ,
652+ relPath.generic_string ()));
653+ }
654+ }
655+
656+ auto out = root / relPath.lexically_normal ();
657+ std::error_code ec;
658+ std::filesystem::create_directories (out.parent_path (), ec);
659+ if (ec) {
660+ return std::unexpected (std::format (
661+ " cannot create directory for generated file '{}': {}" ,
662+ out.string (), ec.message ()));
663+ }
664+
665+ std::ofstream os (out, std::ios::binary);
666+ if (!os) {
667+ return std::unexpected (std::format (
668+ " cannot write generated file '{}'" , out.string ()));
669+ }
670+ os << content;
671+ if (!os) {
672+ return std::unexpected (std::format (
673+ " failed while writing generated file '{}'" , out.string ()));
674+ }
675+ }
676+ return {};
677+ }
678+
630679bool is_std_module (std::string_view name) {
631680 return name == " std" || name == " std.compat" ;
632681}
@@ -1714,6 +1763,11 @@ prepare_build(bool print_fingerprint,
17141763 }
17151764 }
17161765
1766+ if (auto r = materialize_generated_files (effRoot, *manifest); !r) {
1767+ return std::unexpected (std::format (
1768+ " dependency '{}': {}" , depName, r.error ()));
1769+ }
1770+
17171771 return std::pair{effRoot, std::move (*manifest)};
17181772 };
17191773
0 commit comments