rexglue-skate3/cmake/ppc_test_pipeline.cmake
2026-05-18 22:41:13 +01:00

97 lines
3.6 KiB
CMake

# cmake/ppc_test_pipeline.cmake
# PPC assembly test build pipeline
# Provides ppc_add_test_binary() for assembling, linking, and generating
# symbol maps from PPC assembly test files.
# Locate PPC toolchain in tools/ directory
set(PPC_TOOLS_DIR "${PROJECT_SOURCE_DIR}/tools/binutils")
if(WIN32)
set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as.exe")
set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld.exe")
set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm.exe")
else()
set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as")
set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld")
set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm")
endif()
# Verify toolchain exists
if(NOT EXISTS "${PPC_ASSEMBLER}")
message(FATAL_ERROR "PPC assembler not found at ${PPC_ASSEMBLER}")
endif()
if(NOT EXISTS "${PPC_LINKER}")
message(FATAL_ERROR "PPC linker not found at ${PPC_LINKER}")
endif()
message(STATUS "PowerPC assembler: ${PPC_ASSEMBLER}")
message(STATUS "PowerPC linker: ${PPC_LINKER}")
# Convert Windows paths to Cygwin paths for binutils (Windows only)
function(_ppc_convert_to_cygwin_path WINDOWS_PATH OUTPUT_VAR)
if(WIN32 AND WINDOWS_PATH MATCHES "^([A-Za-z]):")
string(REGEX REPLACE "^([A-Za-z]):" "/cygdrive/\\1" CYGWIN_PATH "${WINDOWS_PATH}")
string(SUBSTRING "${CYGWIN_PATH}" 10 1 DRIVE_LETTER)
string(TOLOWER "${DRIVE_LETTER}" DRIVE_LOWER)
string(REGEX REPLACE "^/cygdrive/[A-Za-z]" "/cygdrive/${DRIVE_LOWER}" CYGWIN_PATH "${CYGWIN_PATH}")
string(REPLACE "\\" "/" CYGWIN_PATH "${CYGWIN_PATH}")
set(${OUTPUT_VAR} "${CYGWIN_PATH}" PARENT_SCOPE)
else()
set(${OUTPUT_VAR} "${WINDOWS_PATH}" PARENT_SCOPE)
endif()
endfunction()
# Add a PPC test binary from an assembly file.
# Assembles .s -> .o, links .o -> .bin, generates .o -> .map.
# Appends output files to PPC_TEST_BINS, PPC_TEST_MAPS, PPC_TEST_OBJS
# global properties.
function(ppc_add_test_binary ASM_FILE OBJ_DIR BIN_DIR)
get_filename_component(BASE_NAME ${ASM_FILE} NAME_WE)
set(OBJ_FILE ${OBJ_DIR}/${BASE_NAME}.o)
set(BIN_FILE ${BIN_DIR}/${BASE_NAME}.bin)
set(MAP_FILE ${BIN_DIR}/${BASE_NAME}.map)
_ppc_convert_to_cygwin_path("${OBJ_FILE}" OBJ_FILE_CYGWIN)
_ppc_convert_to_cygwin_path("${BIN_FILE}" BIN_FILE_CYGWIN)
_ppc_convert_to_cygwin_path("${MAP_FILE}" MAP_FILE_CYGWIN)
_ppc_convert_to_cygwin_path("${ASM_FILE}" ASM_FILE_CYGWIN)
# Assemble .s to .o
add_custom_command(
OUTPUT ${OBJ_FILE}
COMMAND ${PPC_ASSEMBLER}
-a32 -be -mregnames -mpower7 -maltivec -mvsx -mvmx128 -R
-o ${OBJ_FILE_CYGWIN}
${ASM_FILE_CYGWIN}
DEPENDS ${ASM_FILE}
COMMENT "Assembling ${BASE_NAME}.s"
VERBATIM
)
# Link .o to .bin
add_custom_command(
OUTPUT ${BIN_FILE}
COMMAND ${PPC_LINKER}
-A powerpc:common32 -melf32ppc -EB -nostdlib
--oformat=binary -Ttext=0x82010000 -e 0x82010000
-o ${BIN_FILE_CYGWIN}
${OBJ_FILE_CYGWIN}
DEPENDS ${OBJ_FILE}
COMMENT "Linking ${BASE_NAME}.bin"
VERBATIM
)
# Generate symbol map
add_custom_command(
OUTPUT ${MAP_FILE}
COMMAND ${PPC_NM} --numeric-sort ${OBJ_FILE_CYGWIN} > ${MAP_FILE}
DEPENDS ${OBJ_FILE}
COMMENT "Generating symbol map for ${BASE_NAME}"
VERBATIM
)
set_property(GLOBAL APPEND PROPERTY PPC_TEST_BINS ${BIN_FILE})
set_property(GLOBAL APPEND PROPERTY PPC_TEST_MAPS ${MAP_FILE})
set_property(GLOBAL APPEND PROPERTY PPC_TEST_OBJS ${OBJ_FILE})
endfunction()