Skip to content

Commit cd2db96

Browse files
authored
Splice the softfp shims before the sysroot leaves for stage 2 (#179)
The shims were a dependency of finalize-sdk and of nothing else. A producer does not run finalize-sdk: it builds the sysroot target, tars the target half and hands it to stage 2. So the archives it exported had never been patched, and stage 2 failed the ABI contract test with checking the softfp ABI shims (23 functions) resolve against the shim missing sceGxmSetViewport resolved against the softfp shim wrapper which is the check doing its job two jobs away from the cause. The first softfp build in CI is where this surfaced; the container builds it was verified in are single-stage, and there finalize-sdk runs. The two lists were the problem, not the missing entry. They are mutually exclusive -- a producer exports, everything else finalizes -- so anything added to one and forgotten in the other stays invisible until something reads the result. Name the target half once and let both wait for it; the splice belongs to that list, at the point where the world is known to be softfp. Stage 2 is excluded because it imports the archives already spliced and builds no components, so there is no softfp-shim target there to wait for. The test reads both recipes and refuses either naming the splice itself, which is what let them drift.
1 parent 0a518f9 commit cd2db96

4 files changed

Lines changed: 79 additions & 13 deletions

File tree

CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,27 @@ if(NOT VITASDK_TARGET_ONLY)
303303
endif()
304304
include(cmake/recipes/BuildGccFinal.cmake)
305305
include(cmake/recipes/Provenance.cmake)
306+
307+
# What the target half is made of, named once because two things wait for it:
308+
# the export that hands stage 2 a sysroot, and the finalize barrier of a build
309+
# that keeps its own. One of them forgetting a piece is invisible until
310+
# something reads the result -- the softfp shims were spliced by finalize-sdk
311+
# and not by the export, so a staged build shipped stage 2 a sysroot whose
312+
# stub archives had never been patched, and the ABI contract test found it
313+
# there rather than here.
314+
set(target_half_dependencies
315+
${gcc_final_barrier}
316+
vita-headers
317+
newlib
318+
pthread-embedded
319+
samples
320+
${version_info_file})
321+
if(VITASDK_FLOAT_ABI STREQUAL "softfp" AND NOT VITASDK_STAGE1_DIR)
322+
# Stage 2 imports the archives already spliced; there is nothing to splice
323+
# and no softfp-shim target, since the components are not built there.
324+
list(APPEND target_half_dependencies softfp-shim)
325+
endif()
326+
306327
if(VITASDK_TARGET_ONLY)
307328
include(cmake/recipes/ExportSysroot.cmake)
308329
else()

cmake/recipes/ExportSysroot.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ add_custom_target(sysroot
4343
-P ${CMAKE_SOURCE_DIR}/cmake/CopySysroot.cmake
4444
COMMAND ${CMAKE_COMMAND} -E tar "cfj" ${CMAKE_BINARY_DIR}/${sysroot_tarball} vitasdk
4545
WORKING_DIRECTORY ${sysroot_root}
46-
DEPENDS ${gcc_final_barrier} vita-headers newlib pthread-embedded samples
47-
${version_info_file}
46+
DEPENDS ${target_half_dependencies}
4847
COMMENT "Exporting the target half to ${sysroot_tarball}"
4948
VERBATIM
5049
)

cmake/recipes/FinalizeSdk.cmake

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,12 @@ set(finalize_sdk_dependencies
3333
vita-toolchain_${target_suffix}
3434
binutils_${target_suffix}
3535
gdb_${target_suffix}
36-
vita-headers
37-
newlib
38-
pthread-embedded
39-
samples
4036
vdpm
4137
vita-makepkg
42-
${gcc_final_barrier}
43-
${version_info_file})
38+
${target_half_dependencies})
4439
if(BUILD_PACMAN_CLIENT)
4540
list(APPEND finalize_sdk_dependencies package-client-configuration)
4641
endif()
47-
if(VITASDK_FLOAT_ABI STREQUAL "softfp")
48-
# Splice the softfp shims into the stub archives before finalize-sdk
49-
# strips them (cmake/strip_target_objects.cmake), not after.
50-
list(APPEND finalize_sdk_dependencies softfp-shim)
51-
endif()
5242

5343
# Target objects are stripped where they are produced. In stage 2 they arrive
5444
# already stripped from stage 1, and the objcopy that would do it belongs to
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# The export and the finalize barrier wait for the same target half.
2+
#
3+
# They are mutually exclusive -- a producer exports a sysroot for stage 2, any
4+
# other build finalizes its own -- so a piece added to one and forgotten in the
5+
# other is invisible until something reads the result. The softfp shims were
6+
# spliced by finalize-sdk and not by the export, so a staged build handed
7+
# stage 2 a sysroot whose stub archives had never been patched, and the ABI
8+
# contract test found it two jobs later.
9+
10+
cmake_minimum_required(VERSION 3.16)
11+
12+
get_filename_component(repository_root "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
13+
set(failures 0)
14+
15+
function(expect_contains path needle description)
16+
file(READ "${repository_root}/${path}" contents)
17+
string(FIND "${contents}" "${needle}" position)
18+
if(position EQUAL -1)
19+
message(SEND_ERROR "FAIL: ${description}")
20+
math(EXPR failures "${failures} + 1")
21+
set(failures ${failures} PARENT_SCOPE)
22+
endif()
23+
endfunction()
24+
25+
function(expect_absent path needle description)
26+
file(READ "${repository_root}/${path}" contents)
27+
string(FIND "${contents}" "${needle}" position)
28+
if(NOT position EQUAL -1)
29+
message(SEND_ERROR "FAIL: ${description}")
30+
endif()
31+
endfunction()
32+
33+
# Both consumers take the list; neither spells the target half out again.
34+
expect_contains("cmake/recipes/ExportSysroot.cmake"
35+
"DEPENDS \${target_half_dependencies}"
36+
"the sysroot export does not wait for the target half")
37+
expect_contains("cmake/recipes/FinalizeSdk.cmake"
38+
"\${target_half_dependencies})"
39+
"finalize-sdk does not wait for the target half")
40+
41+
# The splice belongs to the list and nowhere else, or the two drift again.
42+
expect_absent("cmake/recipes/ExportSysroot.cmake" "softfp-shim"
43+
"ExportSysroot.cmake names softfp-shim itself instead of taking the list")
44+
expect_absent("cmake/recipes/FinalizeSdk.cmake" "softfp-shim"
45+
"FinalizeSdk.cmake names softfp-shim itself instead of taking the list")
46+
47+
# A softfp world whose shims were never spliced is a toolchain that
48+
# miscompiles quietly, so the list carries them exactly when the world is one.
49+
expect_contains("CMakeLists.txt"
50+
"list(APPEND target_half_dependencies softfp-shim)"
51+
"the softfp splice is not part of the target half")
52+
expect_contains("CMakeLists.txt"
53+
"VITASDK_FLOAT_ABI STREQUAL \"softfp\""
54+
"nothing decides when the splice belongs to the target half")
55+
56+
message(STATUS "target half dependency tests passed")

0 commit comments

Comments
 (0)