# file : tests/recipe/cxx/testscript # license : MIT; see accompanying LICENSE file # Ad hoc C++ recipes not supported in a statically-linked build system. Also # disable when cross-testing for the sake of simplicity. # if (!$static && $test.target == $build.host) { +mkdir build +cat <=build/bootstrap.build project = test amalgamation = subprojects = using config using test EOI +cat <=build/root.build EOI +cat <=buildfile ./: {{ c++ 1 // Dummy recipe to trigger cleanup. }} EOI +export BDEP_SYNC=0 : update-clean : { echo 'bar' >=bar; cat <=buildfile; foo: bar % update clean {{ c++ 1 recipe apply (action a, target& xt) const override { file& t (xt.as ()); t.derive_path (); inject_fsdir (a, t); match_prerequisite_members (a, t); switch (a) { case perform_update_id: return perform_update; case perform_clean_id: return perform_clean_depdb; default: assert (false); return noop_recipe; } } static target_state perform_update (action a, const target& xt) { const file& t (xt.as ()); const path& tp (t.path ()); timestamp mt (t.load_mtime ()); auto pr (execute_prerequisites (a, t, mt)); bool update (!pr.first); target_state r (update ? target_state::changed : *pr.first); const file& s (pr.second); const path& sp (s.path ()); depdb dd (tp + ".d"); dd.expect (sp); if (dd.writing () || dd.mtime > mt) update = true; dd.close (); if (!update) return r; if (verb == 1) text << "cp " << t; else if (verb >= 2) text << "cp " << sp << ' ' << tp; cpfile (sp, tp); return target_state::changed; } }} EOI $* 2>>~%EOE%; %^(c\+\+|ld).*%+ cp file{foo} EOE cat <<'bar'; # While at it, make sure there is no rebuild. # $* 2>/'info: dir{./} is up to date'; $* clean 2>- } : test : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % test {{ c++ 1 -- #include -- recipe apply (action a, target& t) const override { if (a.outer ()) { match_inner (a, t); return execute_inner; } else return perform_test; } static target_state perform_test (action, const target& xt) { const file& t (xt.as ()); const path& tp (t.path ()); if (verb == 1) text << "test " << t; else if (verb >= 2) text << "cat " << tp; ifdstream ifs (tp); if (ifs.peek () != ifdstream::traits_type::eof ()) std::cerr << ifs.rdbuf (); ifs.close (); return target_state::changed; } }} EOI $* test 2>>~%EOE%; %^(c\+\+|ld).*%+ cp file{foo} test file{foo} bar EOE $* clean 2>- } : rule : { cat <=buildfile; alias{far}: alias{bar} alias{bar}: alias{~'/f(.+)/'}: alias{~'/b\1/'} {{ c++ 1 -- #include -- recipe apply (action, target&) const override { return [this] (action a, const target& t) { return perform_update (a, t); }; } target_state perform_update (action, const target& t) const { const auto& mr (t.data ()); text << pattern->rule_name << ": " << mr.str (1); return target_state::changed; } }} EOI $* 2>>~%EOE% %^(c\+\+|ld).*%+ : ar EOE } # Clean recipe builds if the testscript is enabled (see above for details). # -$* clean 2>- }