diff options
| author | spicyjpeg <thatspicyjpeg@gmail.com> | 2022-10-09 20:26:25 +0200 |
|---|---|---|
| committer | spicyjpeg <thatspicyjpeg@gmail.com> | 2022-10-09 20:26:25 +0200 |
| commit | 1b1e9b85a51444751dddc0e94a09d19bd4f0885e (patch) | |
| tree | e44b66adea043c59a2be05683edc8bd4ab6982db | |
| parent | 82a259240d9c63d4656b9dae0b46a3689840473b (diff) | |
| download | psn00bsdk-1b1e9b85a51444751dddc0e94a09d19bd4f0885e.tar.gz | |
Refactor CMake scripts, add separate debug/release builds
| -rw-r--r-- | CMakeLists.txt | 40 | ||||
| -rw-r--r-- | examples/lowlevel/cartrom/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indev/psxpad/makefile | 39 | ||||
| -rw-r--r-- | libpsn00b/CMakeLists.txt | 57 | ||||
| -rw-r--r-- | libpsn00b/cmake/flags.cmake | 96 | ||||
| -rw-r--r-- | libpsn00b/cmake/internal_setup.cmake | 230 | ||||
| -rw-r--r-- | libpsn00b/cmake/sdk.cmake | 9 |
7 files changed, 216 insertions, 257 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f255a2..bb6c5ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ include(ExternalProject) project( PSn00bSDK LANGUAGES NONE - VERSION 0.20 + VERSION 0.21 DESCRIPTION "Open source PlayStation 1 SDK" HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" ) @@ -89,11 +89,17 @@ set( -DPSN00BSDK_BUILD_DATE:STRING=${PSN00BSDK_BUILD_DATE} -DPSN00BSDK_GIT_TAG:STRING=${PSN00BSDK_GIT_TAG} -DPSN00BSDK_GIT_COMMIT:STRING=${PSN00BSDK_GIT_COMMIT} - -DMKPSXISO_NO_LIBFLAC:BOOL=${MKPSXISO_NO_LIBFLAC} +) +set( + _tools_args + ${_common_args} + -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/tree -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DMKPSXISO_NO_LIBFLAC:BOOL=${MKPSXISO_NO_LIBFLAC} ) set( - _sdk_args + _libpsn00b_args ${_common_args} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/tree @@ -103,6 +109,7 @@ set( ${_common_args} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${PROJECT_BINARY_DIR}/tree/${CMAKE_INSTALL_LIBDIR}/libpsn00b/cmake/sdk.cmake -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/examples + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} ) # Ensure PSn00bSDK isn't being built using the toolchain file from PSn00bSDK @@ -120,35 +127,42 @@ endif() ExternalProject_Add( tools + PREFIX subprojects SOURCE_DIR ${PROJECT_SOURCE_DIR}/tools - BINARY_DIR tools-build - CMAKE_CACHE_ARGS ${_sdk_args} + CMAKE_CACHE_ARGS ${_tools_args} INSTALL_DIR tree ) ExternalProject_Add( mkpsxiso + PREFIX subprojects SOURCE_DIR ${PROJECT_SOURCE_DIR}/tools/mkpsxiso - BINARY_DIR mkpsxiso-build - CMAKE_CACHE_ARGS ${_sdk_args} + CMAKE_CACHE_ARGS ${_tools_args} + INSTALL_DIR tree +) +ExternalProject_Add( + libpsn00b-debug + PREFIX subprojects + SOURCE_DIR ${PROJECT_SOURCE_DIR}/libpsn00b + CMAKE_GENERATOR ${LIBPSN00B_GENERATOR} + CMAKE_CACHE_ARGS ${_libpsn00b_args} -DCMAKE_BUILD_TYPE:STRING=Debug INSTALL_DIR tree ) ExternalProject_Add( - libpsn00b + libpsn00b-release + PREFIX subprojects SOURCE_DIR ${PROJECT_SOURCE_DIR}/libpsn00b - BINARY_DIR libpsn00b-build CMAKE_GENERATOR ${LIBPSN00B_GENERATOR} - CMAKE_CACHE_ARGS ${_sdk_args} + CMAKE_CACHE_ARGS ${_libpsn00b_args} -DCMAKE_BUILD_TYPE:STRING=Release INSTALL_DIR tree - #DEPENDS tools ) ExternalProject_Add( examples + PREFIX subprojects SOURCE_DIR ${PROJECT_SOURCE_DIR}/examples - BINARY_DIR examples-build CMAKE_GENERATOR ${LIBPSN00B_GENERATOR} CMAKE_CACHE_ARGS ${_examples_args} INSTALL_DIR examples - DEPENDS libpsn00b tools mkpsxiso + DEPENDS libpsn00b-debug libpsn00b-release tools mkpsxiso EXCLUDE_FROM_ALL ${SKIP_EXAMPLES} ) diff --git a/examples/lowlevel/cartrom/CMakeLists.txt b/examples/lowlevel/cartrom/CMakeLists.txt index 7d5e86e..2efe6cf 100644 --- a/examples/lowlevel/cartrom/CMakeLists.txt +++ b/examples/lowlevel/cartrom/CMakeLists.txt @@ -17,7 +17,7 @@ file(GLOB _sources *.c *.s) # executable has to be created manually and converted into raw binary format # (for testing on emulators or flashing to a cheat cartridge). add_executable (cartrom ${_sources}) -target_link_libraries(cartrom psn00bsdk_static_exe) +target_link_libraries(cartrom psn00bsdk_exe_nogprel) set_target_properties(cartrom PROPERTIES PREFIX "" SUFFIX ".elf") target_link_options (cartrom PRIVATE -T${PROJECT_SOURCE_DIR}/rom.ld) diff --git a/indev/psxpad/makefile b/indev/psxpad/makefile deleted file mode 100644 index ab6a733..0000000 --- a/indev/psxpad/makefile +++ /dev/null @@ -1,39 +0,0 @@ -include ../../examples/sdk-common.mk - -TARGET = libpad.elf - -CFILES = $(notdir $(wildcard *.c)) -CPPFILES = $(notdir $(wildcard *.cpp)) -AFILES = $(notdir $(wildcard *.s)) - -OFILES = $(addprefix build/,$(CFILES:.c=.o) $(CPPFILES:.cpp=.o) $(AFILES:.s=.o)) - -INCLUDE += -LIBDIRS += - -LIBS = -lsiofs -lpsxsio -lpsxetc -lpsxgpu -lpsxgte -lpsxspu -lpsxapi -lc - -CFLAGS = -g -O2 -fno-builtin -fdata-sections -ffunction-sections -CPPFLAGS = $(CFLAGS) -fno-exceptions -AFLAGS = -g -msoft-float -LDFLAGS = -g -Ttext=0x80010000 -gc-sections -T $(GCC_BASE)/mipsel-unknown-elf/lib/ldscripts/elf32elmip.x - -CC = $(PREFIX)gcc -CXX = $(PREFIX)g++ -AS = $(PREFIX)as -LD = $(PREFIX)ld - -all: $(OFILES) - $(LD) $(LDFLAGS) $(LIBDIRS) $(OFILES) $(LIBS) -o $(TARGET) - elf2x -q $(TARGET) - -build/%.o: %.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ - -build/%.o: %.s - @mkdir -p $(dir $@) - $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ - -clean: - rm -rf build $(TARGET) $(TARGET:.elf=.exe) diff --git a/libpsn00b/CMakeLists.txt b/libpsn00b/CMakeLists.txt index a662448..71cc659 100644 --- a/libpsn00b/CMakeLists.txt +++ b/libpsn00b/CMakeLists.txt @@ -13,11 +13,7 @@ project( HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" ) -if(NOT DEFINED PSN00BSDK_LIBGCC) - message(FATAL_ERROR "Failed to obtain information about the GCC toolchain. Check your toolchain settings.") -elseif(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() +include(${PROJECT_SOURCE_DIR}/cmake/flags.cmake) ## Libraries @@ -31,37 +27,36 @@ foreach(_library IN LISTS PSN00BSDK_LIBRARIES) file( GLOB_RECURSE _sources - ${_path}/*.s - ${_path}/*.c - ${_path}/*.cpp - ${_path}/*.cxx + ${_path}/*.s ${_path}/*.c ${_path}/*.cpp ) - psn00bsdk_add_library(${_library} STATIC ${_sources}) -endforeach() + foreach(_suffix IN ITEMS _exe_nogprel _exe_gprel _dll) + set(_name ${_library}${_suffix}) + list(APPEND _libraries ${_name}) -psn00bsdk_target_incbin(psxgpu PRIVATE _gpu_debug_font psxgpu/dbugfont.tim) + psn00bsdk_add_library(${_name} STATIC ${_sources}) + target_link_libraries(${_name} PUBLIC psn00bsdk${_suffix}) + endforeach() +endforeach() -# Extract libgcc's contents and merge them into libc after building. -# Unfortunately glob expressions won't work on Windows, so we have to manually -# enumerate the contents of libgcc and save the list to a temporary file (as it -# is too long to be passed directly on the command line). This is actually the -# most reliable way I found to do this (I tried $<TARGET_OBJECTS> to no avail). -add_custom_command( - TARGET c POST_BUILD - COMMAND ${CMAKE_AR} t ${PSN00BSDK_LIBGCC} $<ANGLE-R>_libgcc.txt - COMMAND ${CMAKE_AR} x ${PSN00BSDK_LIBGCC} - COMMAND ${CMAKE_AR} q $<TARGET_FILE:c> \@_libgcc.txt - COMMAND ${CMAKE_AR} s $<TARGET_FILE:c> - #COMMAND ${CMAKE_AR} rsuU $<TARGET_FILE:c> *.o - COMMENT "Merging libgcc contents into SDK libc" -) +# Add binary assets to each version of the libraries. +foreach(_suffix IN ITEMS _exe_nogprel _exe_gprel _dll) + psn00bsdk_target_incbin( + psxgpu${_suffix} PRIVATE _gpu_debug_font + psxgpu/dbugfont.tim + ) +endforeach() ## Installation install( - TARGETS ${PSN00BSDK_LIBRARIES} - DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b + TARGETS + psn00bsdk_common + psn00bsdk_exe_gprel + psn00bsdk_exe_nogprel + psn00bsdk_dll + ${_libraries} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b/$<LOWER_CASE:$<CONFIG>> EXPORT libpsn00b ) install( @@ -95,9 +90,11 @@ install( ) # Generate an import script, which will be used by the setup script to find the -# libraries. +# libraries. Note that CMake actually generates two separate import scripts +# (one setting configuration-specific options), so this won't create conflicts +# once the debug and release builds are merged into the same installation tree. install( EXPORT libpsn00b - DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b/cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b #EXPORT_LINK_INTERFACE_LIBRARIES ) diff --git a/libpsn00b/cmake/flags.cmake b/libpsn00b/cmake/flags.cmake index 5d9c751..fea26cd 100644 --- a/libpsn00b/cmake/flags.cmake +++ b/libpsn00b/cmake/flags.cmake @@ -1,40 +1,23 @@ -# 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 +## Options common to all target types -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 +# - Define PSN00BSDK=1 +# - Always generate debug symbols (stripped by elf2x) # - 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 + +add_library(psn00bsdk_common INTERFACE) target_compile_options( psn00bsdk_common INTERFACE # CPU options @@ -52,6 +35,7 @@ target_compile_options( -nostdlib # Other options -g + -Wa,--strip-local-absolute -fdata-sections -ffunction-sections -fsigned-char @@ -73,16 +57,20 @@ target_link_options( ) target_compile_definitions( psn00bsdk_common INTERFACE - PLAYSTATION=1 + PSN00BSDK=1 $<$<CONFIG:DEBUG>:DEBUG=1> ) -# Options for executables without support for dynamic linking: +## 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) +# - $gp-relative addressing enabled only for local symbols +# - ABI-compatible calls disabled (incompatible with $gp-relative addressing) + +add_library(psn00bsdk_exe_gprel INTERFACE) +target_link_libraries(psn00bsdk_exe_gprel INTERFACE psn00bsdk_common) target_compile_options( - psn00bsdk_static_exe INTERFACE + psn00bsdk_exe_gprel INTERFACE -G8 -fno-pic -mno-abicalls @@ -90,50 +78,42 @@ target_compile_options( -mno-extern-sdata ) target_link_options( - psn00bsdk_static_exe INTERFACE + psn00bsdk_exe_gprel INTERFACE -G8 -static ) -# Options for executables with support for dynamic linking: +## Options for executables with support for dynamic linking + # - Position-independent code disabled -# - GP-relative addressing disabled +# - $gp-relative addressing disabled # - ABI-compatible calls disabled (must be performed manually) + +add_library(psn00bsdk_exe_nogprel INTERFACE) +target_link_libraries(psn00bsdk_exe_nogprel INTERFACE psn00bsdk_common) target_compile_options( - psn00bsdk_dynamic_exe INTERFACE + psn00bsdk_exe_nogprel INTERFACE -G0 -fno-pic -mno-abicalls -mno-gpopt ) target_link_options( - psn00bsdk_dynamic_exe INTERFACE + psn00bsdk_exe_nogprel 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 - -G0 - -fno-pic - -mno-abicalls - -mno-gpopt - -Wa,--strip-local-absolute -) - -target_link_libraries(psn00bsdk_object_lib INTERFACE psn00bsdk_static_lib) +## Options for dynamically-linked libraries -# Options for dynamically-loaded libraries: # - Position-independent code enabled -# - GP-relative addressing disabled (incompatible with ABI calls) +# - $gp-relative addressing disabled (incompatible with ABI calls) # - ABI-compatible calls enabled + +add_library(psn00bsdk_dll INTERFACE) +target_link_libraries(psn00bsdk_dll INTERFACE psn00bsdk_common) target_compile_options( - psn00bsdk_shared_lib INTERFACE + psn00bsdk_dll INTERFACE -G0 -fPIC -mabicalls @@ -141,11 +121,7 @@ target_compile_options( -mshared ) target_link_options( - psn00bsdk_shared_lib INTERFACE + psn00bsdk_dll INTERFACE -G0 -shared ) - -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..e9f0db5 100644 --- a/libpsn00b/cmake/internal_setup.cmake +++ b/libpsn00b/cmake/internal_setup.cmake @@ -1,5 +1,5 @@ # 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. @@ -7,6 +7,10 @@ cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) +# Re-enable support for dynamic linking as CMake's "Generic" system type +# disables it. +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS ON) + # Fetch SDK version information from build.json. if(NOT DEFINED PSN00BSDK_VERSION) file(READ ${CMAKE_CURRENT_LIST_DIR}/../build.json _json) @@ -17,13 +21,9 @@ 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") +include(${CMAKE_CURRENT_LIST_DIR}/../libpsn00b.cmake OPTIONAL) -## SDK libraries +## Settings (can be overridden by projects) # DON'T CHANGE THE ORDER or you'll break the libraries' internal dependencies. set( @@ -40,33 +40,23 @@ set( c ) -include(${CMAKE_CURRENT_LIST_DIR}/libpsn00b.cmake OPTIONAL) -include(${CMAKE_CURRENT_LIST_DIR}/flags.cmake) +set(PSN00BSDK_EXECUTABLE_LINK_LIBRARIES ${PSN00BSDK_LIBRARIES}) +set(PSN00BSDK_SHARED_LIBRARY_LINK_LIBRARIES "") -# 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_SUFFIX ".exe") +set(PSN00BSDK_SHARED_LIBRARY_SUFFIX ".dll") +set(PSN00BSDK_SYMBOL_MAP_SUFFIX ".map") - 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)" - ) +## 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 +## Tool paths set( PSN00BSDK_TOOLS @@ -80,26 +70,41 @@ 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) -endif() +# 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}) -# psn00bsdk_add_executable( -# <target name> <STATIC|DYNAMIC> -# [EXCLUDE_FROM_ALL] -# <sources> ... -# ) -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)") + 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_property(TARGET gcc PROPERTY IMPORTED_LOCATION ${PSN00BSDK_LIBGCC}) + link_libraries(gcc) +endif() + +## Target helpers + +function(psn00bsdk_add_executable name type) # Throw an error if elf2x was not found (which should never happen if the # SDK is installed properly). if(ELF2X STREQUAL "ELF2X-NOTFOUND") @@ -107,10 +112,10 @@ 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) + psn00bsdk_target_link_sdk (${name} PRIVATE EXECUTABLE ${type} ${PSN00BSDK_EXECUTABLE_LINK_LIBRARIES}) target_include_directories(${name} PRIVATE ${PSN00BSDK_INCLUDE}) # Add post-build steps to generate the .exe and symbol map once the @@ -123,30 +128,26 @@ function(psn00bsdk_add_executable name type) ) 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 "^(STATIC|OBJECT)$") + # Remove virtual target dependencies to make sure linking against the + # library does not also propagate static library flags. + add_library (${name} ${_type} ${ARGN}) + set_target_properties(${name} PROPERTIES PREFIX "lib" SUFFIX ".a") + set_target_properties(${name} PROPERTIES INTERFACE_LINK_LIBRARIES "") + target_link_libraries(${name} PRIVATE psn00bsdk_common) - if(${_type} MATCHES "^(shared|module)$") + target_include_directories(${name} PRIVATE ${PSN00BSDK_INCLUDE}) + elseif(_type MATCHES "^(SHARED|MODULE)$") + add_library (${name} ${_type} ${ARGN}) set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX ".so") target_link_options (${name} PRIVATE -T${PSN00BSDK_LDSCRIPTS}/dll.ld) + psn00bsdk_target_link_sdk (${name} PRIVATE SHARED_LIBRARY ${PSN00BSDK_SHARED_LIBRARY_LINK_LIBRARIES}) + target_include_directories(${name} PRIVATE ${PSN00BSDK_INCLUDE}) + # Add a post-build step to dump the DLL's raw contents into a new file # separate from the built ELF. add_custom_command( @@ -155,63 +156,48 @@ function(psn00bsdk_add_library name type) BYPRODUCTS ${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 "") + message(FATAL_ERROR "Invalid library type: ${type} (must be STATIC, OBJECT, SHARED or MODULE)") 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.") +## Linking helpers + +function(psn00bsdk_target_link_sdk name type target_type) + set(_libraries ${ARGN}) + string(TOUPPER ${target_type} _target_type) + + if(_target_type STREQUAL "EXECUTABLE") + list(POP_FRONT _libraries) + string(TOUPPER ${ARGV3} _exe_type) + + if(_exe_type MATCHES "^(STATIC|GPREL)$") + set(_suffix _exe_gprel) + elseif(_exe_type MATCHES "^(DYNAMIC|NOGPREL)$") + set(_suffix _exe_nogprel) + else() + message(FATAL_ERROR "Invalid executable type: ${ARGV3} (must be STATIC, GPREL, DYNAMIC or NOGPREL)") + endif() + elseif(_target_type STREQUAL "SHARED_LIBRARY") + set(_suffix _dll) + else() + message(FATAL_ERROR "Invalid target type: ${target_type} (must be EXECUTABLE or SHARED_LIBRARY)") 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} - ) + list(TRANSFORM _libraries APPEND ${_suffix}) + target_link_libraries(${name} ${type} psn00bsdk${_suffix} ${_libraries}) endfunction() -## Helper functions for assets - -# 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 +232,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 +245,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..37b9fd0 100644 --- a/libpsn00b/cmake/sdk.cmake +++ b/libpsn00b/cmake/sdk.cmake @@ -1,5 +1,5 @@ # PSn00bSDK toolchain setup file for CMake -# (C) 2021 spicyjpeg - MPL licensed +# (C) 2021-2022 spicyjpeg - MPL licensed cmake_minimum_required(VERSION 3.20) @@ -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. |
