| 1 | module builder |
| 2 | |
| 3 | import os |
| 4 | import v2.pref |
| 5 | |
| 6 | // Concern 1: the pre-parse self-host fast relink must never fire for a request |
| 7 | // that gen_cleanc() treats as "generation only" — otherwise a warm-cache |
| 8 | // `-o foo.c cmd/v2/v2.v` links an executable into foo.c instead of writing C. |
| 9 | fn test_fast_relink_skips_generation_only_outputs() { |
| 10 | // A `.c` output is generation-only regardless of how it would be built. |
| 11 | b_c := new_builder(&pref.Preferences{ backend: .cleanc }) |
| 12 | assert b_c.fast_relink_output_is_generation_only('/tmp/v2.c') |
| 13 | assert b_c.fast_relink_output_is_generation_only('out.c') |
| 14 | |
| 15 | // A shared library is generation-only. |
| 16 | b_shared := new_builder(&pref.Preferences{ backend: .cleanc, is_shared_lib: true }) |
| 17 | assert b_shared.fast_relink_output_is_generation_only('/tmp/lib') |
| 18 | |
| 19 | // A normal local executable build is NOT generation-only — the fast relink |
| 20 | // is allowed to proceed (subject to its cache/freshness checks). |
| 21 | b_exe := new_builder(&pref.Preferences{ backend: .cleanc }) |
| 22 | assert b_exe.can_compile_cleanc_locally() // sanity: host target compiles locally |
| 23 | assert !b_exe.fast_relink_output_is_generation_only('/tmp/v3') |
| 24 | } |
| 25 | |
| 26 | // Concern 2: the fast relink trusts the cc/cc_flags recorded in main.stamp, so a |
| 27 | // pre-parse fingerprint of the flag inputs that do NOT need parsing must change |
| 28 | // when the compiler / prod-shared mode / env CFLAGS change, and stay stable |
| 29 | // otherwise. A changed fingerprint is what invalidates a would-be stale relink. |
| 30 | fn test_preparse_flag_fingerprint_tracks_flag_settings() { |
| 31 | base := new_builder(&pref.Preferences{ backend: .cleanc }) |
| 32 | fp0 := base.preparse_flag_fingerprint() |
| 33 | |
| 34 | // Stable for identical settings. |
| 35 | assert new_builder(&pref.Preferences{ backend: .cleanc }).preparse_flag_fingerprint() == fp0 |
| 36 | |
| 37 | // A different C compiler changes it. |
| 38 | b_cc := new_builder(&pref.Preferences{ backend: .cleanc, ccompiler: 'some-other-cc' }) |
| 39 | assert b_cc.preparse_flag_fingerprint() != fp0 |
| 40 | |
| 41 | // -prod changes it (different optimization flags). |
| 42 | b_prod := new_builder(&pref.Preferences{ backend: .cleanc, is_prod: true }) |
| 43 | assert b_prod.preparse_flag_fingerprint() != fp0 |
| 44 | |
| 45 | // -shared changes it (no -flto, different link mode). |
| 46 | b_shared := new_builder(&pref.Preferences{ backend: .cleanc, is_shared_lib: true }) |
| 47 | assert b_shared.preparse_flag_fingerprint() != fp0 |
| 48 | |
| 49 | // Env CFLAGS (V2CFLAGS) change it. |
| 50 | prev := os.getenv('V2CFLAGS') |
| 51 | os.setenv('V2CFLAGS', '-DV2_FAST_RELINK_TEST', true) |
| 52 | fp_env := new_builder(&pref.Preferences{ backend: .cleanc }).preparse_flag_fingerprint() |
| 53 | if prev == '' { |
| 54 | os.unsetenv('V2CFLAGS') |
| 55 | } else { |
| 56 | os.setenv('V2CFLAGS', prev, true) |
| 57 | } |
| 58 | assert fp_env != fp0 |
| 59 | } |
| 60 | |