mirror of
https://github.com/aydencharles/onionHEN.git
synced 2026-10-22 03:42:46 -05:00
200 lines
8.6 KiB
CMake
200 lines
8.6 KiB
CMake
cmake_minimum_required (VERSION 3.20)
|
|
|
|
set(basename "bootstrapper")
|
|
project(${basename} C CXX ASM)
|
|
|
|
onion_module_prologue(C_STANDARD 11 CXX_STANDARD 20)
|
|
|
|
set(D_CWD "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
onion_output_dirs()
|
|
set(D_SRC ${D_CWD}/source)
|
|
|
|
# SVG menu icons are the source of truth. Rasterize them into the build tree so
|
|
# editing an icon cannot leave a stale checked-in PNG embedded in bootstrapper.
|
|
set(_icon_source_dir "${D_CWD}/assets/icons")
|
|
set(_icon_output_dir "${CMAKE_CURRENT_BINARY_DIR}/generated/assets")
|
|
file(GLOB _icon_svg_files CONFIGURE_DEPENDS "${_icon_source_dir}/icon_xml_*.svg")
|
|
|
|
find_program(RSVG_CONVERT_EXECUTABLE NAMES rsvg-convert)
|
|
if(NOT RSVG_CONVERT_EXECUTABLE)
|
|
find_program(IMAGEMAGICK_EXECUTABLE NAMES magick convert)
|
|
endif()
|
|
if(NOT RSVG_CONVERT_EXECUTABLE AND NOT IMAGEMAGICK_EXECUTABLE)
|
|
message(FATAL_ERROR
|
|
"SVG icon conversion requires rsvg-convert (preferred) or ImageMagick")
|
|
endif()
|
|
|
|
set(_generated_icon_files)
|
|
foreach(_svg_file IN LISTS _icon_svg_files)
|
|
get_filename_component(_icon_name "${_svg_file}" NAME_WE)
|
|
set(_png_file "${_icon_output_dir}/${_icon_name}.png")
|
|
if(RSVG_CONVERT_EXECUTABLE)
|
|
add_custom_command(
|
|
OUTPUT "${_png_file}"
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${_icon_output_dir}"
|
|
COMMAND "${RSVG_CONVERT_EXECUTABLE}" --width 64 --height 64
|
|
--output "${_png_file}" "${_svg_file}"
|
|
DEPENDS "${_svg_file}"
|
|
COMMENT "Rasterizing ${_icon_name}.svg"
|
|
VERBATIM
|
|
)
|
|
else()
|
|
add_custom_command(
|
|
OUTPUT "${_png_file}"
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${_icon_output_dir}"
|
|
COMMAND "${IMAGEMAGICK_EXECUTABLE}" -background none "${_svg_file}"
|
|
-resize 64x64 "${_png_file}"
|
|
DEPENDS "${_svg_file}"
|
|
COMMENT "Rasterizing ${_icon_name}.svg"
|
|
VERBATIM
|
|
)
|
|
endif()
|
|
list(APPEND _generated_icon_files "${_png_file}")
|
|
endforeach()
|
|
|
|
# These raster-only icons do not have SVG sources. Copy them into the same
|
|
# generated directory so daemon.c has one stable asset location.
|
|
foreach(_raster_icon IN ITEMS
|
|
icon_xml_monitor.png
|
|
icon_xml_network.png
|
|
icon_xml_author_avatar.png
|
|
icon_xml_donator_ljf.png
|
|
icon_xml_donator_szx.png
|
|
icon_xml_donator_aglx.png
|
|
icon_xml_donator_xiaomao.png
|
|
icon_xml_donator_xie.png)
|
|
set(_raster_source "${D_CWD}/assets/${_raster_icon}")
|
|
set(_raster_output "${_icon_output_dir}/${_raster_icon}")
|
|
add_custom_command(
|
|
OUTPUT "${_raster_output}"
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${_icon_output_dir}"
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_raster_source}" "${_raster_output}"
|
|
DEPENDS "${_raster_source}"
|
|
COMMENT "Copying ${_raster_icon}"
|
|
VERBATIM
|
|
)
|
|
list(APPEND _generated_icon_files "${_raster_output}")
|
|
endforeach()
|
|
|
|
# Generate the icon embedding blocks and the runtime manifest from the icon
|
|
# list above. Previously each icon had to be added in three hand-maintained
|
|
# places — a 12-line .incbin block in daemon.c, an extern pair in main.cpp and
|
|
# a write_blob_file() call — none of which fail the build when forgotten.
|
|
set(_icon_asm "${_icon_output_dir}/icon_assets.inc")
|
|
set(_icon_manifest "${_icon_output_dir}/icon_manifest.inc")
|
|
set(_asm_body "/* Generated by CMake from bootstrapper/assets — do not edit. */\n")
|
|
set(_manifest_body "/* Generated by CMake from bootstrapper/assets — do not edit. */\n")
|
|
foreach(_icon_file IN LISTS _generated_icon_files)
|
|
get_filename_component(_icon_name "${_icon_file}" NAME_WE)
|
|
string(APPEND _asm_body
|
|
"\".global ${_icon_name}_start\\n\"\n"
|
|
"\".type ${_icon_name}_start, @object\\n\"\n"
|
|
"\".align 16\\n\"\n"
|
|
"\"${_icon_name}_start:\\n\"\n"
|
|
"\".incbin \\\"\" ONIONHEN_ICON_ASSET_DIR \"/${_icon_name}.png\\\"\\n\"\n"
|
|
"\"${_icon_name}_end:\\n\"\n"
|
|
"\".global ${_icon_name}_size\\n\"\n"
|
|
"\".type ${_icon_name}_size, @object\\n\"\n"
|
|
"\".align 4\\n\"\n"
|
|
"\"${_icon_name}_size:\\n\"\n"
|
|
"\".int ${_icon_name}_end - ${_icon_name}_start\\n\"\n")
|
|
string(APPEND _manifest_body "ONION_ICON(${_icon_name})\n")
|
|
endforeach()
|
|
file(GENERATE OUTPUT "${_icon_asm}" CONTENT "${_asm_body}")
|
|
file(GENERATE OUTPUT "${_icon_manifest}" CONTENT "${_manifest_body}")
|
|
|
|
add_executable(${PROJECT_NAME})
|
|
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}.elf")
|
|
|
|
# Finalize main target sources
|
|
target_compile_options(${PROJECT_NAME} PUBLIC
|
|
$<$<COMPILE_LANGUAGE:C>:${C_DEFS} ${C_FLAGS}>
|
|
$<$<COMPILE_LANGUAGE:CXX>:${CXX_DEFS} ${CXX_FLAGS}>
|
|
$<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>
|
|
)
|
|
target_link_options(${PROJECT_NAME} PRIVATE "-Wl,--gc-sections" "-Wl,--icf=safe")
|
|
|
|
# Byepervisor removed from OnionHEN — bootstrapper sources only.
|
|
# pt.c / elfldr.c live in libonion_elfldr (raise_privileges + inject primitives).
|
|
file(GLOB SrcFiles CONFIGURE_DEPENDS ${D_SRC}/*.c ${D_SRC}/*.cpp ${D_SRC}/../include/*.h ${D_SRC}/../include/*.hpp ${D_SRC}/*.s)
|
|
list(FILTER SrcFiles EXCLUDE REGEX ".*/(pt|elfldr)\\.c$")
|
|
|
|
set(CMAKE_C_FLAGS "${ONION_PS5_TARGET_FLAGS} ")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-keyword-macro -fPIC -fPIE -march=znver2 -Wall -Werror -fstack-protector-all -ffunction-sections -fdata-sections")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -gfull -gdwarf-2 -pedantic -pedantic-errors")
|
|
set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG")
|
|
set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG")
|
|
|
|
target_sources(${PROJECT_NAME} PRIVATE ${SrcFiles})
|
|
# .incbin in daemon.c is invisible to the compiler dependency scanner.
|
|
# Without OBJECT_DEPENDS, embedded payload rebuilds do not re-embed into bootstrapper.
|
|
if(DEFINED ONIONHEN_OUT_BIN)
|
|
set(_onion_daemon_elf "${ONIONHEN_OUT_BIN}/daemon.elf")
|
|
set(_onion_util_elf "${ONIONHEN_OUT_BIN}/util.elf")
|
|
set(_onion_elfldr_elf "${ONIONHEN_OUT_BIN}/onion_elfldr.elf")
|
|
else()
|
|
set(_onion_daemon_elf "${PROJECT_ROOT}/bin/daemon.elf")
|
|
set(_onion_util_elf "${PROJECT_ROOT}/bin/util.elf")
|
|
set(_onion_elfldr_elf "${PROJECT_ROOT}/bin/onion_elfldr.elf")
|
|
endif()
|
|
set_source_files_properties(
|
|
${D_SRC}/daemon.c
|
|
PROPERTIES OBJECT_DEPENDS
|
|
"${_onion_daemon_elf};${_onion_util_elf};${_onion_elfldr_elf};${ONIONHEN_KSTUFF_ELF};${D_CWD}/assets/onionhen_sicon.png;${_generated_icon_files}"
|
|
)
|
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
|
ONIONHEN_DAEMON_ELF="${_onion_daemon_elf}"
|
|
ONIONHEN_UTIL_ELF="${_onion_util_elf}"
|
|
ONIONHEN_ELFLDR_ELF="${_onion_elfldr_elf}"
|
|
ONIONHEN_KSTUFF_ELF="${ONIONHEN_KSTUFF_ELF}"
|
|
ONIONHEN_ICON_ASSET_DIR="${_icon_output_dir}"
|
|
)
|
|
# elfldr_raise_privileges from libonion_elfldr; launches go via elfldr_remote.c.
|
|
onion_target_debug_define(${PROJECT_NAME})
|
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
|
"${D_CWD}/include"
|
|
# icon_assets.inc / icon_manifest.inc
|
|
"${_icon_output_dir}"
|
|
"${PROJECT_ROOT}/libonion_proc/include"
|
|
"${PROJECT_ROOT}/libonion_platform/include"
|
|
"${PROJECT_ROOT}/libonion_settings/include"
|
|
"${PROJECT_ROOT}/libonion_payload/include"
|
|
"${PROJECT_ROOT}/libonion_conflict/include"
|
|
"${PROJECT_ROOT}/libonion_elfldr/include"
|
|
"${PROJECT_ROOT}/include"
|
|
)
|
|
target_link_directories (${PROJECT_NAME} PUBLIC "${ONIONHEN_PS5_STUB_DIR}")
|
|
target_sources(${PROJECT_NAME} PRIVATE "${ONIONHEN_COMMON_DIR}/elfldr_remote.c")
|
|
target_link_libraries (${PROJECT_NAME} PUBLIC onion_proc onion_platform onion_settings onion_payload onion_conflict onion_ready onion_elfldr kernel_sys SceNotification SceSystemService)
|
|
add_custom_target(${PROJECT_NAME}_assets
|
|
DEPENDS ${_generated_icon_files} "${_icon_asm}" "${_icon_manifest}")
|
|
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_assets)
|
|
add_dependencies(${PROJECT_NAME} daemon util shellui onion_elfldr_server onion_proc onion_platform onion_settings onion_payload onion_conflict onion_ready onion_elfldr)
|
|
|
|
# Copy bootstrapper.elf as test.elf before processing
|
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${PROJECT_NAME}> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test.elf
|
|
COMMENT "Copying ${PROJECT_NAME}.elf to test.elf"
|
|
)
|
|
|
|
# Add post-build command
|
|
onion_strip_debug(${PROJECT_NAME})
|
|
|
|
# Declare the compressed payload as a real build output. The unpacker embeds
|
|
# these files, so a POST_BUILD-only command can otherwise leave it stale until
|
|
# a second Ninja invocation.
|
|
set(_bootstrapper_lzma "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bootstrapper.elf.lzma")
|
|
set(_bootstrapper_lzma_size "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bootstrapper.elf.lzma.size")
|
|
set(_bootstrapper_sha1 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bootstrapper.elf.sha1")
|
|
add_custom_command(
|
|
OUTPUT "${_bootstrapper_lzma}" "${_bootstrapper_lzma_size}" "${_bootstrapper_sha1}"
|
|
COMMAND ${CMAKE_COMMAND} -E env "TARGET_ELF=$<TARGET_FILE:${PROJECT_NAME}>"
|
|
${PROJECT_ROOT}/../scripts/pack_bootstrapper.sh
|
|
DEPENDS ${PROJECT_NAME}
|
|
COMMENT "Packing bootstrapper (lzma + size + sha1 of uncompressed ELF)"
|
|
VERBATIM
|
|
)
|
|
add_custom_target(${PROJECT_NAME}_packed
|
|
DEPENDS "${_bootstrapper_lzma}" "${_bootstrapper_lzma_size}" "${_bootstrapper_sha1}")
|
|
add_dependencies(${PROJECT_NAME}_packed ${PROJECT_NAME})
|