aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/cmake/internal_setup.cmake
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-10-09 20:26:25 +0200
committerspicyjpeg <thatspicyjpeg@gmail.com>2022-10-09 20:26:25 +0200
commit1b1e9b85a51444751dddc0e94a09d19bd4f0885e (patch)
treee44b66adea043c59a2be05683edc8bd4ab6982db /libpsn00b/cmake/internal_setup.cmake
parent82a259240d9c63d4656b9dae0b46a3689840473b (diff)
downloadpsn00bsdk-1b1e9b85a51444751dddc0e94a09d19bd4f0885e.tar.gz
Refactor CMake scripts, add separate debug/release builds
Diffstat (limited to 'libpsn00b/cmake/internal_setup.cmake')
-rw-r--r--libpsn00b/cmake/internal_setup.cmake230
1 files changed, 118 insertions, 112 deletions
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()