Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,27 @@ if(NOT VITASDK_TARGET_ONLY)
endif()
include(cmake/recipes/BuildGccFinal.cmake)
include(cmake/recipes/Provenance.cmake)

# What the target half is made of, named once because two things wait for it:
# the export that hands stage 2 a sysroot, and the finalize barrier of a build
# that keeps its own. One of them forgetting a piece is invisible until
# something reads the result -- the softfp shims were spliced by finalize-sdk
# and not by the export, so a staged build shipped stage 2 a sysroot whose
# stub archives had never been patched, and the ABI contract test found it
# there rather than here.
set(target_half_dependencies
${gcc_final_barrier}
vita-headers
newlib
pthread-embedded
samples
${version_info_file})
if(VITASDK_FLOAT_ABI STREQUAL "softfp" AND NOT VITASDK_STAGE1_DIR)
# Stage 2 imports the archives already spliced; there is nothing to splice
# and no softfp-shim target, since the components are not built there.
list(APPEND target_half_dependencies softfp-shim)
endif()

if(VITASDK_TARGET_ONLY)
include(cmake/recipes/ExportSysroot.cmake)
else()
Expand Down
3 changes: 1 addition & 2 deletions cmake/recipes/ExportSysroot.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ add_custom_target(sysroot
-P ${CMAKE_SOURCE_DIR}/cmake/CopySysroot.cmake
COMMAND ${CMAKE_COMMAND} -E tar "cfj" ${CMAKE_BINARY_DIR}/${sysroot_tarball} vitasdk
WORKING_DIRECTORY ${sysroot_root}
DEPENDS ${gcc_final_barrier} vita-headers newlib pthread-embedded samples
${version_info_file}
DEPENDS ${target_half_dependencies}
COMMENT "Exporting the target half to ${sysroot_tarball}"
VERBATIM
)
12 changes: 1 addition & 11 deletions cmake/recipes/FinalizeSdk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,12 @@ set(finalize_sdk_dependencies
vita-toolchain_${target_suffix}
binutils_${target_suffix}
gdb_${target_suffix}
vita-headers
newlib
pthread-embedded
samples
vdpm
vita-makepkg
${gcc_final_barrier}
${version_info_file})
${target_half_dependencies})
if(BUILD_PACMAN_CLIENT)
list(APPEND finalize_sdk_dependencies package-client-configuration)
endif()
if(VITASDK_FLOAT_ABI STREQUAL "softfp")
# Splice the softfp shims into the stub archives before finalize-sdk
# strips them (cmake/strip_target_objects.cmake), not after.
list(APPEND finalize_sdk_dependencies softfp-shim)
endif()

# Target objects are stripped where they are produced. In stage 2 they arrive
# already stripped from stage 1, and the objcopy that would do it belongs to
Expand Down
56 changes: 56 additions & 0 deletions tests/cmake/target-half-dependencies.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# The export and the finalize barrier wait for the same target half.
#
# They are mutually exclusive -- a producer exports a sysroot for stage 2, any
# other build finalizes its own -- so a piece added to one and forgotten in the
# other is invisible until something reads the result. The softfp shims were
# spliced by finalize-sdk and not by the export, so a staged build handed
# stage 2 a sysroot whose stub archives had never been patched, and the ABI
# contract test found it two jobs later.

cmake_minimum_required(VERSION 3.16)

get_filename_component(repository_root "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
set(failures 0)

function(expect_contains path needle description)
file(READ "${repository_root}/${path}" contents)
string(FIND "${contents}" "${needle}" position)
if(position EQUAL -1)
message(SEND_ERROR "FAIL: ${description}")
math(EXPR failures "${failures} + 1")
set(failures ${failures} PARENT_SCOPE)
endif()
endfunction()

function(expect_absent path needle description)
file(READ "${repository_root}/${path}" contents)
string(FIND "${contents}" "${needle}" position)
if(NOT position EQUAL -1)
message(SEND_ERROR "FAIL: ${description}")
endif()
endfunction()

# Both consumers take the list; neither spells the target half out again.
expect_contains("cmake/recipes/ExportSysroot.cmake"
"DEPENDS \${target_half_dependencies}"
"the sysroot export does not wait for the target half")
expect_contains("cmake/recipes/FinalizeSdk.cmake"
"\${target_half_dependencies})"
"finalize-sdk does not wait for the target half")

# The splice belongs to the list and nowhere else, or the two drift again.
expect_absent("cmake/recipes/ExportSysroot.cmake" "softfp-shim"
"ExportSysroot.cmake names softfp-shim itself instead of taking the list")
expect_absent("cmake/recipes/FinalizeSdk.cmake" "softfp-shim"
"FinalizeSdk.cmake names softfp-shim itself instead of taking the list")

# A softfp world whose shims were never spliced is a toolchain that
# miscompiles quietly, so the list carries them exactly when the world is one.
expect_contains("CMakeLists.txt"
"list(APPEND target_half_dependencies softfp-shim)"
"the softfp splice is not part of the target half")
expect_contains("CMakeLists.txt"
"VITASDK_FLOAT_ABI STREQUAL \"softfp\""
"nothing decides when the splice belongs to the target half")

message(STATUS "target half dependency tests passed")
Loading