@@ -101,8 +101,9 @@ void Ignite::resolve(const std::vector<std::string>& id,
101101 }
102102 }
103103
104- recipe->second .cache = hash (recipe->second );
105- auto cached = std::filesystem::exists (cachefile (recipe->second ));
104+ auto resolved_recipe = recipe->second ;
105+ resolved_recipe.cache = hash (resolved_recipe);
106+ auto cached = std::filesystem::exists (cachefile (resolved_recipe));
106107
107108 for (auto depend : depends) {
108109 auto idx = std::find_if (output.begin (), output.end (),
@@ -128,13 +129,17 @@ void Ignite::resolve(const std::vector<std::string>& id,
128129 }
129130 }
130131 }
131- output.emplace_back (i, recipe-> second , cached);
132+ output.emplace_back (i, resolved_recipe , cached);
132133 };
133134
134135 for (auto const & i : id) { dfs (i); }
135136}
136137
137138std::string Ignite::hash (const Recipe& recipe) {
139+ if (auto it = hash_cache.find (recipe.id ); it != hash_cache.end ()) {
140+ return it->second ;
141+ }
142+
138143 std::string hash_sum;
139144
140145 {
@@ -159,13 +164,16 @@ std::string Ignite::hash(const Recipe& recipe) {
159164 throw std::runtime_error (" missing required element '" + i +
160165 " for " + recipe.id );
161166 }
162- std::stringstream ss;
163- ss << depend_recipe->second .config .node ;
164- picosha2::hash256_hex_string (ss.str () + hash_sum, hash_sum);
167+ // Recursively hash the dependency so transitive changes
168+ // propagate: if a dep-of-dep changes, this recipe's hash
169+ // changes too.
170+ auto dep_hash = hash (depend_recipe->second );
171+ picosha2::hash256_hex_string (dep_hash + hash_sum, hash_sum);
165172 }
166173 }
167174 }
168175
176+ hash_cache[recipe.id ] = hash_sum;
169177 return hash_sum;
170178}
171179
@@ -177,9 +185,9 @@ void Ignite::build(const Recipe& recipe) {
177185 if (access (i.path ().c_str (), W_OK) != 0 ) {
178186 std::error_code code;
179187 std::filesystem::permissions (i.path (),
180- std::filesystem::perms::group_all |
181- std::filesystem::perms::owner_all |
182- std::filesystem::perms::group_all ,
188+ std::filesystem::perms::owner_all |
189+ std::filesystem::perms::group_all |
190+ std::filesystem::perms::others_all ,
183191 code);
184192 }
185193 }
@@ -190,8 +198,9 @@ void Ignite::build(const Recipe& recipe) {
190198 .arg (" -r" )
191199 .arg (" -f" )
192200 .arg (container.host_root )
193- .execute ();
201+ .run ();
194202 });
203+ std::filesystem::create_directories (cache_path / " logs" );
195204 std::ofstream logger (cache_path / " logs" /
196205 (recipe.package_name (recipe.element_id ) + " .log" ));
197206 container.logger = &logger;
@@ -315,7 +324,7 @@ Container Ignite::setup_container(
315324
316325 for (auto const & [path, info, cached] : states) {
317326 auto installation_path = std::filesystem::path (" install-root" ) /
318- recipe.package_name ();
327+ recipe.package_name (recipe. element_id );
319328 installation_path = recipe.config .get <std::string>(
320329 recipe.name () + " -include-path" ,
321330 recipe.config .get <std::string>(
@@ -352,7 +361,7 @@ void Ignite::integrate(Container& container, const Recipe& recipe,
352361 if (root.empty ()) {
353362 extractor.arg (" --exclude=./etc/hosts" )
354363 .arg (" --exclude=./etc/hostname" )
355- .arg (" --exclude=./etc/resolve .conf" )
364+ .arg (" --exclude=./etc/resolv .conf" )
356365 .arg (" --exclude=./proc" )
357366 .arg (" --exclude=./run" )
358367 .arg (" --exclude=./sys" )
@@ -402,7 +411,7 @@ void Ignite::integrate(Container& container, const Recipe& recipe,
402411 .arg (cache_file_path)
403412 .arg (" --exclude=./etc/hosts" )
404413 .arg (" --exclude=./etc/hostname" )
405- .arg (" --exclude=./etc/resolve .conf" )
414+ .arg (" --exclude=./etc/resolv .conf" )
406415 .arg (" --exclude=./proc" )
407416 .arg (" --exclude=./run" )
408417 .arg (" --exclude=./sys" )
@@ -435,7 +444,7 @@ void extract(const std::filesystem::path& filepath,
435444 }
436445
437446 int status = Executor (exe)
438- .arg (" -xvPf " )
447+ .arg (" -xvf " )
439448 .arg (filepath)
440449 .arg (" -C" )
441450 .arg (output_path)
@@ -503,7 +512,7 @@ std::optional<std::filesystem::path> Ignite::prepare_sources(
503512 extract (filepath,
504513 build_root / (subdir ? *subdir : std::filesystem::path (" " )),
505514 files_list);
506- if (!subdir) {
515+ if (!subdir && !files_list. empty () ) {
507516 std::string dir = files_list.front ();
508517 auto idx = dir.find (' /' );
509518 if (idx != std::string::npos) { dir = dir.substr (0 , idx); }
@@ -562,16 +571,21 @@ void Ignite::compile_source(const Recipe& build_info, Container* container,
562571 }
563572
564573 if (build_info.config .get <std::string>(" build-type" , " " ) == " import" ) {
565- auto source = resolved_build_root /
566- build_info.config .get <std::string>(" source" , " " );
567- auto target = resolved_install_root /
568- build_info.config .get <std::string>(" target" , " " );
569- std::filesystem::create_directories (target);
574+ auto source = extra_variables[" build-root" ] /
575+ std::filesystem::path (
576+ build_info.config .get <std::string>(" source" , " " ));
577+ auto target = extra_variables[" install-root" ] /
578+ std::filesystem::path (
579+ build_info.config .get <std::string>(" target" , " " ));
580+ std::filesystem::create_directories (
581+ resolved_install_root /
582+ build_info.config .get <std::string>(" target" , " " ));
570583 Executor (" /bin/cp" )
571584 .arg (" -rap" )
572585 .arg (source / " ." )
573586 .arg (" -t" )
574587 .arg (target)
588+ .container (container)
575589 .execute ();
576590 } else {
577591 auto script = build_info.config .get <std::string>(" script" , " " );
@@ -584,7 +598,6 @@ void Ignite::compile_source(const Recipe& build_info, Container* container,
584598 script = build_info.resolve (script, config, extra_variables);
585599
586600 std::cout << " Exec(script)" << std::endl;
587- std::cout << " Exec(pre-script)" << std::endl;
588601
589602 if (script.length () > 500 ) {
590603 auto script_path = resolved_build_root / " pkgupd_exec_script.sh" ;
@@ -633,15 +646,28 @@ void Ignite::compile_source(const Recipe& build_info, Container* container,
633646
634647void Ignite::strip (const Recipe& build_info, Container* container,
635648 const std::filesystem::path& install_root) {
649+ std::vector<std::string> mime_to_strip;
650+ if (config.node [" strip-mimetype" ]) {
651+ for (auto const & i : config.node [" strip-mimetype" ]) {
652+ mime_to_strip.emplace_back (i.as <std::string>());
653+ }
654+ }
655+ if (build_info.config .node [" strip-mimetype" ]) {
656+ for (auto const & i : build_info.config .node [" strip-mimetype" ]) {
657+ mime_to_strip.emplace_back (i.as <std::string>());
658+ }
659+ }
660+
636661 for (auto const & iter :
637662 std::filesystem::recursive_directory_iterator (install_root)) {
638663 if (!iter.is_regular_file ()) continue ;
639664 // if file is executable and writable or
640665 // if file ends with .so and .a
641- // TODO check if it cover all cases
642666 if (((iter.path ().has_extension () &&
643667 (iter.path ().extension () == " .so" ||
644- iter.path ().extension () == " .a" )) ||
668+ iter.path ().extension () == " .a" ||
669+ iter.path ().filename ().string ().find (" .so." ) !=
670+ std::string::npos)) ||
645671 (access (iter.path ().c_str (), X_OK) == 0 )) &&
646672 access (iter.path ().c_str (), W_OK) == 0 ) {
647673 auto [status, mime_type] = Executor (" /bin/file" )
@@ -656,19 +682,6 @@ void Ignite::strip(const Recipe& build_info, Container* container,
656682 continue ;
657683 }
658684
659- std::vector<std::string> mime_to_strip;
660- if (config.node [" strip-mimetype" ]) {
661- for (auto const & i : config.node [" strip-mimetype" ]) {
662- mime_to_strip.emplace_back (i.as <std::string>());
663- }
664- }
665-
666- if (build_info.config .node [" strip-mimetype" ]) {
667- for (auto const & i : build_info.config .node [" strip-mimetype" ]) {
668- mime_to_strip.emplace_back (i.as <std::string>());
669- }
670- }
671-
672685 if (std::find (mime_to_strip.begin (), mime_to_strip.end (),
673686 mime_type) == mime_to_strip.end ()) {
674687 continue ;
@@ -684,13 +697,15 @@ void Ignite::strip(const Recipe& build_info, Container* container,
684697 .silent ()
685698 .execute ();
686699
700+ auto fname = iter.path ().filename ().string ();
687701 std::string strip_args = " --strip-all" ;
688- if (iter.path ().has_extension ()) {
689- if (iter.path ().extension () == " .a" ) {
690- strip_args = " --strip-debug" ;
691- } else {
692- strip_args = " --strip-unneeded" ;
693- }
702+ if (iter.path ().has_extension () &&
703+ iter.path ().extension () == " .a" ) {
704+ strip_args = " --strip-debug" ;
705+ } else if ((iter.path ().has_extension () &&
706+ iter.path ().extension () == " .so" ) ||
707+ fname.find (" .so." ) != std::string::npos) {
708+ strip_args = " --strip-unneeded" ;
694709 }
695710
696711 // Strip out the debugging symbols
@@ -765,19 +780,33 @@ void Ignite::pack(const Recipe& build_info, Container* container,
765780 }
766781 }
767782
783+ // Collect paths first; modifying the tree during recursive_directory_iterator
784+ // is undefined behavior.
785+ std::vector<std::filesystem::path> dirs_to_clean;
786+ std::vector<std::filesystem::path> files_to_remove;
787+ std::vector<std::filesystem::path> dbg_to_move;
788+ bool clean_empty_dirs = build_info.config .get <bool >(" clean-empty-dir" , true );
789+
768790 for (auto const & i : std::filesystem::recursive_directory_iterator (
769791 install_root_package)) {
770792 if (i.is_directory ()) {
771- if (i.path ().empty () &&
772- build_info.config .get <bool >(" clean-empty-dir" , true )) {
773- std::filesystem::remove (i.path ());
774- }
793+ if (clean_empty_dirs) { dirs_to_clean.push_back (i.path ()); }
775794 } else if (!keep_files.empty () && keep_file (i.path ().filename ())) {
776795 continue ;
777796 } else if (i.path ().has_extension () && i.path ().extension () == " .la" ) {
778- std::filesystem::remove (i.path ());
797+ files_to_remove. push_back (i.path ());
779798 } else if (i.path ().has_extension () && i.path ().extension () == " .dbg" ) {
780- move_file (i.path (), install_root_dbg);
799+ dbg_to_move.push_back (i.path ());
800+ }
801+ }
802+
803+ for (auto const & p : files_to_remove) { std::filesystem::remove (p); }
804+ for (auto const & p : dbg_to_move) { move_file (p, install_root_dbg); }
805+ // Reverse so children are removed before parents, allowing cascading cleanup.
806+ std::reverse (dirs_to_clean.begin (), dirs_to_clean.end ());
807+ for (auto const & p : dirs_to_clean) {
808+ if (std::filesystem::exists (p) && std::filesystem::is_empty (p)) {
809+ std::filesystem::remove (p);
781810 }
782811 }
783812
0 commit comments