diff options
| author | John "Lameguy" Wilbert Villamor <lameguy64@gmail.com> | 2022-10-19 17:57:06 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-19 17:57:06 +0800 |
| commit | e08a3d9366f8ca14a76b3dd569dac1fb9f569748 (patch) | |
| tree | 33654513b0b184c27f8035dbc405640fcbeb44ab /libpsn00b/cmake | |
| parent | c4a2533d21dfd05cde841ea48c67b05e0e6a853f (diff) | |
| parent | 9b2ffc6078a850b7d354855cca7622090b41f30c (diff) | |
| download | psn00bsdk-e08a3d9366f8ca14a76b3dd569dac1fb9f569748.tar.gz | |
Merge pull request #59 from spicyjpeg/psxmdec
IRQ handler fix, .STR playback example, multiple library builds (v0.21)
Diffstat (limited to 'libpsn00b/cmake')
| -rw-r--r-- | libpsn00b/cmake/flags.cmake | 161 | ||||
| -rw-r--r-- | libpsn00b/cmake/internal_setup.cmake | 285 | ||||
| -rw-r--r-- | libpsn00b/cmake/sdk.cmake | 23 |
3 files changed, 219 insertions, 250 deletions
diff --git a/libpsn00b/cmake/flags.cmake b/libpsn00b/cmake/flags.cmake index 5d9c751..1ca25c2 100644 --- a/libpsn00b/cmake/flags.cmake +++ b/libpsn00b/cmake/flags.cmake @@ -1,151 +1,90 @@ -# libpsn00b interface targets -# (C) 2021 spicyjpeg - MPL licensed +# PSn00bSDK interface targets +# (C) 2021-2022 spicyjpeg - MPL licensed # This script creates several "virtual" targets (psn00bsdk_*) that set include -# directories and compiler flags when a target is linked against them. The -# following targets are currently defined: -# - psn00bsdk_common -# - psn00bsdk_static_exe -# - psn00bsdk_dynamic_exe -# - psn00bsdk_static_lib -# - psn00bsdk_object_lib (same as psn00bsdk_static_lib) -# - psn00bsdk_shared_lib -# - psn00bsdk_module_lib (same as psn00bsdk_shared_lib) -# -# NOTE: building a static library and linking it as part of a DLL is currently -# *not* supported. +# directories and compiler flags when a target is linked against them. It is +# only used when building libpsn00b, as CMake automatically saves these targets +# into the export script once libpsn00b is installed. -if(NOT TARGET psn00bsdk_common) # Include guard +add_library (psn00bsdk INTERFACE) +link_libraries(psn00bsdk) -add_library(psn00bsdk_common INTERFACE) - -foreach( - _target IN ITEMS - static_exe dynamic_exe static_lib object_lib shared_lib module_lib -) - add_library (psn00bsdk_${_target} INTERFACE) - target_link_libraries(psn00bsdk_${_target} INTERFACE psn00bsdk_common) -endforeach() - -# Options common to all target types: -# - Define PLAYSTATION=1 -# - Optimize for MIPS R3000 -# - Inject zero checks into division operations (will throw breaks) -# - All standard libraries (including libgcc) disabled -# - Put all symbols into separate sections when building -# - C++ features that require runtime support disabled -# - Unused section stripping enabled target_compile_options( - psn00bsdk_common INTERFACE - # CPU options - -msoft-float - -march=r3000 - -mtune=r3000 - -mabi=32 - -mno-mt - -mno-llsc - -mdivide-breaks + psn00bsdk INTERFACE + # Options common to all target types + -g + -Wa,--strip-local-absolute -O2 - # Standard library options -ffreestanding -fno-builtin -nostdlib - # Other options - -g -fdata-sections -ffunction-sections -fsigned-char -fno-strict-overflow -fdiagnostics-color=always + -msoft-float + -march=r3000 + -mtune=r3000 + -mabi=32 + -mno-mt + -mno-llsc + -mdivide-breaks $<$<COMPILE_LANGUAGE:CXX>: - # C++ options + # Options common to all target types (C++) -fno-exceptions -fno-rtti -fno-unwind-tables -fno-threadsafe-statics -fno-use-cxa-atexit > -) -target_link_options( - psn00bsdk_common INTERFACE - -nostdlib - -Wl,-gc-sections -) -target_compile_definitions( - psn00bsdk_common INTERFACE - PLAYSTATION=1 - $<$<CONFIG:DEBUG>:DEBUG=1> -) - -# Options for executables without support for dynamic linking: -# - Position-independent code disabled -# - GP-relative addressing enabled only for local symbols -# - ABI-compatible calls disabled (incompatible with GP-relative addr) -target_compile_options( - psn00bsdk_static_exe INTERFACE + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,EXECUTABLE_GPREL>: + # Options for executables with $gp-relative addressing -G8 -fno-pic -mno-abicalls -mgpopt -mno-extern-sdata -) -target_link_options( - psn00bsdk_static_exe INTERFACE - -G8 - -static -) - -# Options for executables with support for dynamic linking: -# - Position-independent code disabled -# - GP-relative addressing disabled -# - ABI-compatible calls disabled (must be performed manually) -target_compile_options( - psn00bsdk_dynamic_exe INTERFACE - -G0 - -fno-pic - -mno-abicalls - -mno-gpopt -) -target_link_options( - psn00bsdk_dynamic_exe INTERFACE - -G0 - -static -) - -# Options for static libraries: -# - Position-independent code disabled -# - GP-relative addressing disabled -# - ABI-compatible calls disabled -# - Local stripping enabled -target_compile_options( - psn00bsdk_static_lib INTERFACE + > + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,EXECUTABLE_NOGPREL>: + # Options for executables without $gp-relative addressing -G0 -fno-pic -mno-abicalls -mno-gpopt - -Wa,--strip-local-absolute -) - -target_link_libraries(psn00bsdk_object_lib INTERFACE psn00bsdk_static_lib) - -# Options for dynamically-loaded libraries: -# - Position-independent code enabled -# - GP-relative addressing disabled (incompatible with ABI calls) -# - ABI-compatible calls enabled -target_compile_options( - psn00bsdk_shared_lib INTERFACE + > + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,SHARED_LIBRARY>: + # Options for DLLs -G0 -fPIC -mabicalls -mno-gpopt -mshared + > ) target_link_options( - psn00bsdk_shared_lib INTERFACE + psn00bsdk INTERFACE + # Options common to all target types + -nostdlib + -Wl,-gc-sections + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,EXECUTABLE_GPREL>: + # Options for executables with $gp-relative addressing + -G8 + -static + > + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,EXECUTABLE_NOGPREL>: + # Options for executables without $gp-relative addressing + -G0 + -static + > + $<$<STREQUAL:$<UPPER_CASE:$<TARGET_PROPERTY:PSN00BSDK_TARGET_TYPE>>,SHARED_LIBRARY>: + # Options for DLLs -G0 -shared + > +) +target_compile_definitions( + psn00bsdk INTERFACE + PSN00BSDK=1 + $<$<CONFIG:Release>:NDEBUG=1> ) - -target_link_libraries(psn00bsdk_module_lib INTERFACE psn00bsdk_shared_lib) - -endif() diff --git a/libpsn00b/cmake/internal_setup.cmake b/libpsn00b/cmake/internal_setup.cmake index d293127..e78355f 100644 --- a/libpsn00b/cmake/internal_setup.cmake +++ b/libpsn00b/cmake/internal_setup.cmake @@ -1,12 +1,29 @@ # PSn00bSDK internal setup script for CMake -# (C) 2021 spicyjpeg - MPL licensed +# (C) 2021-2022 spicyjpeg - MPL licensed # This script is included automatically when using the toolchain file and # defines helper functions. -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) include(GNUInstallDirs) +## CMake configuration + +# Setting these variables and properties would technically be the toolchain +# script's responsibility, however they are overridden by project() so their +# setting is deferred to this script. +set(CMAKE_EXECUTABLE_SUFFIX ".elf") +set(CMAKE_STATIC_LIBRARY_PREFIX "lib") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") +set(CMAKE_SHARED_MODULE_PREFIX "") +set(CMAKE_SHARED_MODULE_SUFFIX ".so") + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS ON) + +## PSn00bSDK initialization + # Fetch SDK version information from build.json. if(NOT DEFINED PSN00BSDK_VERSION) file(READ ${CMAKE_CURRENT_LIST_DIR}/../build.json _json) @@ -17,13 +34,10 @@ if(NOT DEFINED PSN00BSDK_VERSION) string(JSON PSN00BSDK_GIT_COMMIT GET ${_json} git_commit) endif() -## Settings (can be overridden by projects) - -set(PSN00BSDK_EXECUTABLE_SUFFIX ".exe") -set(PSN00BSDK_SHARED_LIBRARY_SUFFIX ".dll") -set(PSN00BSDK_SYMBOL_MAP_SUFFIX ".map") - -## SDK libraries +include(${CMAKE_CURRENT_LIST_DIR}/../libpsn00b.cmake OPTIONAL) +if(TARGET psn00bsdk) + link_libraries(psn00bsdk) +endif() # DON'T CHANGE THE ORDER or you'll break the libraries' internal dependencies. set( @@ -40,33 +54,33 @@ set( c ) -include(${CMAKE_CURRENT_LIST_DIR}/libpsn00b.cmake OPTIONAL) -include(${CMAKE_CURRENT_LIST_DIR}/flags.cmake) +## Settings (can be overridden by projects) -# Use the toolchain path to find libgcc (used to build libpsn00b). Of course -# different installers, packages and distros have different opinions when it -# comes to deciding where to install toolchains, so we have to bruteforce -# multiple combinations of paths. -if(CMAKE_C_COMPILER_VERSION) - string(REGEX MATCH "^([0-9]+)\." _dummy ${CMAKE_C_COMPILER_VERSION}) +set(PSN00BSDK_EXECUTABLE_LINK_LIBRARIES ${PSN00BSDK_LIBRARIES}) +set(PSN00BSDK_SHARED_LIBRARY_LINK_LIBRARIES "") - find_library( - PSN00BSDK_LIBGCC gcc - HINTS - ${PSN00BSDK_TC}/lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} - ${PSN00BSDK_TC}/lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} - ${PSN00BSDK_TC}/lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} - ${PSN00BSDK_TC}/lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} - ${PSN00BSDK_TC}/../lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} - ${PSN00BSDK_TC}/../lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} - ${PSN00BSDK_TC}/../lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} - ${PSN00BSDK_TC}/../lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} - NO_DEFAULT_PATH - DOC "Path to libgcc (bundled with the GCC toolchain)" - ) +set(PSN00BSDK_EXECUTABLE_SUFFIX ".exe") +set(PSN00BSDK_SHARED_LIBRARY_SUFFIX ".dll") +set(PSN00BSDK_SYMBOL_MAP_SUFFIX ".map") + +define_property( + TARGET PROPERTY PSN00BSDK_TARGET_TYPE + BRIEF_DOCS "Type of this target (EXECUTABLE_GPREL, EXECUTABLE_NOGPREL or SHARED_LIBRARY)" + FULL_DOCS "Type of this target (if executable or DLL) or of the executable/DLL this target is going to be linked to (if static library)" +) + +## Include paths + +set(PSN00BSDK_LDSCRIPTS ${CMAKE_CURRENT_LIST_DIR}/../ldscripts) +if(IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../include) + set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../include) +else() + set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../../../include/libpsn00b) endif() -## Tools +include_directories(AFTER ${PSN00BSDK_INCLUDE}) + +## Tool paths set( PSN00BSDK_TOOLS @@ -80,24 +94,49 @@ find_program(SMXLINK smxlink HINTS ${PSN00BSDK_TOOLS}) find_program(LZPACK lzpack HINTS ${PSN00BSDK_TOOLS}) find_program(MKPSXISO mkpsxiso HINTS ${PSN00BSDK_TOOLS}) -## Helper functions for executables +## libgcc -set(PSN00BSDK_LDSCRIPTS ${CMAKE_CURRENT_LIST_DIR}/../ldscripts) -if(IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../include) - set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../include) -else() - set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../../../include/libpsn00b) +# Use the toolchain path to find libgcc. Of course different installers, +# packages and distros have different opinions when it comes to deciding where +# to install toolchains, so we have to bruteforce multiple combinations of +# paths. +if(CMAKE_C_COMPILER_VERSION) + string(REGEX MATCH "^([0-9]+)\." _dummy ${CMAKE_C_COMPILER_VERSION}) + + find_library( + PSN00BSDK_LIBGCC gcc #REQUIRED + HINTS + ${PSN00BSDK_TC}/lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} + ${PSN00BSDK_TC}/lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} + ${PSN00BSDK_TC}/lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} + ${PSN00BSDK_TC}/lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} + ${PSN00BSDK_TC}/../lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} + ${PSN00BSDK_TC}/../lib/gcc-cross/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} + ${PSN00BSDK_TC}/../lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_C_COMPILER_VERSION} + ${PSN00BSDK_TC}/../lib/gcc/${PSN00BSDK_TARGET}/${CMAKE_MATCH_1} + NO_DEFAULT_PATH + DOC "Path to libgcc (bundled with the GCC toolchain)" + ) + if(PSN00BSDK_LIBGCC STREQUAL "PSN00BSDK_LIBGCC-NOTFOUND") + message(FATAL_ERROR "Failed to find libgcc in the GCC toolchain's files. Check your toolchain settings, or set the path to libgcc using -DPSN00BSDK_LIBGCC.") + endif() + + add_library (gcc STATIC IMPORTED) + set_target_properties(gcc PROPERTIES IMPORTED_LOCATION ${PSN00BSDK_LIBGCC}) + link_libraries (gcc) endif() -# psn00bsdk_add_executable( -# <target name> <STATIC|DYNAMIC> -# [EXCLUDE_FROM_ALL] -# <sources> ... -# ) +## Target helpers + function(psn00bsdk_add_executable name type) - string(TOLOWER ${type} _type) - if(NOT ${_type} MATCHES "^(static|dynamic)$") - message(FATAL_ERROR "Invalid executable type: ${type} (must be STATIC or DYNAMIC)") + string(TOUPPER ${type} _type) + + if(_type MATCHES "^(STATIC|GPREL)$") + set(_type EXECUTABLE_GPREL) + elseif(_type MATCHES "^(DYNAMIC|NOGPREL)$") + set(_type EXECUTABLE_NOGPREL) + else() + message(FATAL_ERROR "Invalid executable type: ${type} (must be STATIC, GPREL, DYNAMIC or NOGPREL)") endif() # Throw an error if elf2x was not found (which should never happen if the @@ -107,111 +146,79 @@ function(psn00bsdk_add_executable name type) endif() add_executable (${name} ${ARGN}) - target_link_libraries(${name} psn00bsdk_${_type}_exe ${PSN00BSDK_LIBRARIES}) - set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX ".elf") - target_link_options (${name} PRIVATE -T${PSN00BSDK_LDSCRIPTS}/exe.ld) - - target_include_directories(${name} PRIVATE ${PSN00BSDK_INCLUDE}) + set_target_properties(${name} PROPERTIES PSN00BSDK_TARGET_TYPE ${_type}) + target_link_libraries(${name} PRIVATE ${PSN00BSDK_EXECUTABLE_LINK_LIBRARIES}) + target_link_options (${name} PRIVATE -T$<SHELL_PATH:${PSN00BSDK_LDSCRIPTS}/exe.ld>) # Add post-build steps to generate the .exe and symbol map once the # executable is built. + # FIXME: CMake does not (yet) allow target-dependent generator expressions + # to specify the byproducts, so we have to make sure the generated files + # have no prefix/suffix and are in the current build directory. + #set(_repl PATH:REPLACE_EXTENSION,LAST_ONLY,$<TARGET_FILE:${name}>) add_custom_command( - TARGET ${name} POST_BUILD - COMMAND ${ELF2X} -q ${name}.elf ${name}${PSN00BSDK_EXECUTABLE_SUFFIX} - COMMAND ${TOOLCHAIN_NM} -f posix -l -n ${name}.elf $<ANGLE-R>${name}${PSN00BSDK_SYMBOL_MAP_SUFFIX} - BYPRODUCTS ${name}${PSN00BSDK_EXECUTABLE_SUFFIX} ${name}${PSN00BSDK_SYMBOL_MAP_SUFFIX} + TARGET ${name} POST_BUILD + COMMAND + ${ELF2X} -q + $<SHELL_PATH:$<TARGET_FILE:${name}>> + #$<SHELL_PATH:$<${_repl},${PSN00BSDK_EXECUTABLE_SUFFIX}>> + $<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_EXECUTABLE_SUFFIX}> + COMMAND + ${TOOLCHAIN_NM} -f posix -l -n + $<SHELL_PATH:$<TARGET_FILE:${name}>> + #$<ANGLE-R>$<SHELL_PATH:$<${_repl},${PSN00BSDK_SYMBOL_MAP_SUFFIX}>> + $<ANGLE-R>$<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_SYMBOL_MAP_SUFFIX}> + BYPRODUCTS + #$<${_repl},${PSN00BSDK_EXECUTABLE_SUFFIX}> + #$<${_repl},${PSN00BSDK_SYMBOL_MAP_SUFFIX}> + ${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_EXECUTABLE_SUFFIX} + ${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_SYMBOL_MAP_SUFFIX} ) endfunction() -# psn00bsdk_add_library( -# <target name> <STATIC|SHARED|MODULE> -# [EXCLUDE_FROM_ALL] -# <sources> ... -# ) -# Note that SHARED and MODULE have the same meaning (both will create a DLL). -# SDK libraries are NOT statically linked in by default; if you need to link -# something, use target_link_libraries() manually. function(psn00bsdk_add_library name type) - string(TOUPPER ${type} _type_upper) - string(TOLOWER ${type} _type) - if(NOT ${_type} MATCHES "^(static|object|shared|module)$") - message(FATAL_ERROR "Invalid library type: ${type} (must be STATIC, OBJECT, SHARED or MODULE)") - endif() + string(TOUPPER ${type} _type) - add_library (${name} ${_type_upper} ${ARGN}) - target_link_libraries(${name} psn00bsdk_${_type}_lib) - - target_include_directories(${name} PRIVATE ${PSN00BSDK_INCLUDE}) - - if(${_type} MATCHES "^(shared|module)$") - set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX ".so") - target_link_options (${name} PRIVATE -T${PSN00BSDK_LDSCRIPTS}/dll.ld) + if(_type MATCHES "^(STATIC|OBJECT)$") + add_library (${name} ${_type} ${ARGN}) + #target_link_libraries(${name} PRIVATE psn00bsdk) + elseif(_type MATCHES "^(SHARED|MODULE)$") + add_library (${name} ${_type} ${ARGN}) + set_target_properties(${name} PROPERTIES PSN00BSDK_TARGET_TYPE SHARED_LIBRARY) + target_link_libraries(${name} PRIVATE ${PSN00BSDK_SHARED_LIBRARY_LINK_LIBRARIES}) + target_link_options (${name} PRIVATE -T$<SHELL_PATH:${PSN00BSDK_LDSCRIPTS}/dll.ld>) # Add a post-build step to dump the DLL's raw contents into a new file # separate from the built ELF. + #set(_repl PATH:REPLACE_EXTENSION,LAST_ONLY,$<TARGET_FILE:${name}>) add_custom_command( - TARGET ${name} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} -O binary ${name}.so ${name}${PSN00BSDK_SHARED_LIBRARY_SUFFIX} - BYPRODUCTS ${name}${PSN00BSDK_SHARED_LIBRARY_SUFFIX} + TARGET ${name} POST_BUILD + COMMAND + ${CMAKE_OBJCOPY} -O binary + $<SHELL_PATH:$<TARGET_FILE:${name}>> + #$<SHELL_PATH:$<${_repl},${PSN00BSDK_SHARED_LIBRARY_SUFFIX}>> + $<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_SHARED_LIBRARY_SUFFIX}> + #BYPRODUCTS $<${_repl},${PSN00BSDK_SHARED_LIBRARY_SUFFIX}> + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${name}${PSN00BSDK_SHARED_LIBRARY_SUFFIX} ) else() - set_target_properties(${name} PROPERTIES PREFIX "lib" SUFFIX ".a") - - # Remove virtual target dependencies to make sure linking against the - # library does not also propagate static library flags. - set_target_properties(${name} PROPERTIES INTERFACE_LINK_LIBRARIES "") - endif() -endfunction() - -# psn00bsdk_add_cd_image( -# <target name> -# <image file name> -# <mkpsxiso config template> -# [DEPENDS <dependencies> ...] -# [additional options passed to add_custom_target()] -# ) -function(psn00bsdk_add_cd_image name image_name config_file) - # Throw an error if mkpsxiso was not found. Performing this check manually - # (instead of just marking mkpsxiso as required) allows simple projects to - # be built even if mkpsxiso is not installed. - if(MKPSXISO STREQUAL "MKPSXISO-NOTFOUND") - message(FATAL_ERROR "Failed to locate mkpsxiso. If mkpsxiso wasn't installed alongside the SDK, check your PATH environment variable.") + message(FATAL_ERROR "Invalid library type: ${type} (must be STATIC, OBJECT, SHARED or MODULE)") endif() - - cmake_path(HASH config_file _hash) - - set(CD_IMAGE_NAME ${image_name}) - set(CD_CONFIG_FILE cd_image_${_hash}.xml) - configure_file(${config_file} ${CD_CONFIG_FILE}) - - add_custom_target( - ${name} ALL - COMMAND ${MKPSXISO} -y ${CD_CONFIG_FILE} - BYPRODUCTS ${image_name}.bin ${image_name}.cue - COMMENT "Building CD image ${image_name}" - ${ARGN} - ) endfunction() -## Helper functions for assets +## Linking helpers -# psn00bsdk_target_incbin_a( -# <existing target name> <PRIVATE|PUBLIC|INTERFACE> -# <data symbol name> -# <size symbol name> -# <path to binary file> -# <linker section name> -# <alignment> -# ) function(psn00bsdk_target_incbin_a name type symbol_name size_name path section align) string(MAKE_C_IDENTIFIER ${symbol_name} _id) string(MAKE_C_IDENTIFIER ${size_name} _size) cmake_path(ABSOLUTE_PATH path OUTPUT_VARIABLE _path) + string(SHA1 _hash "${name} ${_id}") + set(_asm_file ${CMAKE_CURRENT_BINARY_DIR}/incbin_${_hash}.s) + # Generate an assembly source file that includes the binary file and add it # to the target's sources. The file is also added as a depedency to ensure # CMake builds it before the target (if it's not a static file). - set(_asm_file ${PROJECT_BINARY_DIR}/incbin_${name}_${_id}.s) file( CONFIGURE OUTPUT ${_asm_file} @@ -246,11 +253,6 @@ ${_size}: set_source_files_properties(${_asm_file} PROPERTIES OBJECT_DEPENDS ${_path}) endfunction() -# psn00bsdk_target_incbin( -# <existing target name> <PRIVATE|PUBLIC|INTERFACE> -# <symbol name> -# <path to binary file> -# ) function(psn00bsdk_target_incbin name type symbol_name path) string(MAKE_C_IDENTIFIER ${symbol_name} _id) @@ -264,3 +266,28 @@ function(psn00bsdk_target_incbin name type symbol_name path) 4 ) endfunction() + +## CD image and asset helpers + +function(psn00bsdk_add_cd_image name image_name config_file) + # Throw an error if mkpsxiso was not found. Performing this check manually + # (instead of just marking mkpsxiso as required) allows simple projects to + # be built even if mkpsxiso is not installed. + if(MKPSXISO STREQUAL "MKPSXISO-NOTFOUND") + message(FATAL_ERROR "Failed to locate mkpsxiso. If mkpsxiso wasn't installed alongside the SDK, check your PATH environment variable.") + endif() + + cmake_path(HASH config_file _hash) + + set(CD_IMAGE_NAME ${image_name}) + set(CD_CONFIG_FILE cd_image_${_hash}.xml) + configure_file(${config_file} ${CD_CONFIG_FILE}) + + add_custom_target( + ${name} ALL + COMMAND ${MKPSXISO} -y ${CD_CONFIG_FILE} + BYPRODUCTS ${image_name}.bin ${image_name}.cue + COMMENT "Building CD image ${image_name}" + ${ARGN} + ) +endfunction() diff --git a/libpsn00b/cmake/sdk.cmake b/libpsn00b/cmake/sdk.cmake index 8965e79..facee26 100644 --- a/libpsn00b/cmake/sdk.cmake +++ b/libpsn00b/cmake/sdk.cmake @@ -1,7 +1,7 @@ # PSn00bSDK toolchain setup file for CMake -# (C) 2021 spicyjpeg - MPL licensed +# (C) 2021-2022 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) set( PSN00BSDK_TC "" @@ -14,7 +14,7 @@ set( ## CMake configuration -set(CMAKE_SYSTEM_NAME PlayStation) +set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR mipsel) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) @@ -28,6 +28,11 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PSN00BSDK_TC PSN00BSDK_TARGET PSN00BSDK_VERSION) +# Always generate compile_commands.json alongside build scripts. This allows +# some IDEs and tools (such as clangd) to automatically configure include +# directories and other options. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + ## Toolchain path setup # Attempt to find GCC using a list of common installation locations. @@ -65,10 +70,9 @@ endif() ## Toolchain executables -# ${CMAKE_EXECUTABLE_SUFFIX} seems not to work in toolchain scripts, so we -# can't rely on it to determine the host OS extension for executables. The best -# workaround I found is to extract the extension from the path returned by -# find_program() using a regex. +# As we have overridden ${CMAKE_EXECUTABLE_SUFFIX} we can't rely on it to +# determine the host OS extension for executables. A workaround is to extract +# the extension from the path returned by find_program() using a regex. set(_prefix ${_bin}/${PSN00BSDK_TARGET}) string(REGEX MATCH ".+-gcc(.*)$" _dummy ${_gcc}) @@ -85,7 +89,6 @@ set(TOOLCHAIN_NM ${_prefix}-nm${CMAKE_MATCH_1}) ## SDK setup -# We can't set up the SDK here as the find_*() functions may fail if they are -# called before project(). We can however set a script to be executed right -# after project() is invoked. +# Continue initialization by running internal_setup.cmake after project() is +# invoked. set(CMAKE_PROJECT_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/internal_setup.cmake) |
