aboutsummaryrefslogtreecommitdiff
path: root/doc/cmake_reference.md
blob: 3c89da310e500c29367791d939e3aab9c18f6c4f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

# PSn00bSDK CMake reference

## Setup

The only requirement to use the SDK in CMake is to set the
`CMAKE_TOOLCHAIN_FILE` variable to `INSTALL_PATH/lib/libpsn00b/cmake/sdk.cmake`
(where `INSTALL_PATH` is the install prefix PSn00bSDK is installed to). This
can be done on the command line (`-DCMAKE_TOOLCHAIN_FILE=...`), in
`CMakeLists.txt` (before calling `project()`) or using a
[preset](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html).

It's suggested to have a default preset that sets `CMAKE_TOOLCHAIN_FILE` to
`$env{PSN00BSDK_LIBS}/cmake/sdk.cmake`, so the `PSN00BSDK_LIBS` environment
variable (used by former PSn00bSDK versions) is respected. Such a preset can be
created by placing a `CMakePresets.json` file in the project's root with the
following contents:

```json
{
  "version": 2,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name":        "default",
      "displayName": "Default configuration",
      "description": "Use this preset to build the project using PSn00bSDK.",
      "generator":   "Ninja",
      "binaryDir":   "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE":     "Debug",
        "CMAKE_TOOLCHAIN_FILE": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake",
        "PSN00BSDK_TC":         "",
        "PSN00BSDK_TARGET":     "mipsel-none-elf"
      }
    }
  ]
}
```

To avoid having to pass variables to CMake each time the project is built, a
second presets file named `CMakeUserPresets.json` can be created and populated
with hardcoded values in the `cacheVariables` section. This file can be kept
private (e.g. by adding it to `.gitignore`); CMake will automatically load
presets from it instead of `CMakePresets.json` if it exists.

See the [template](../template/CMakeLists.txt) for an example CMake script
showing how to build a simple project.

## Targets

These targets are defined when using PSn00bSDK. There is no need to explicitly
link against any of these, as the helper commands (see below) handle linking
behind the scenes. To avoid conflicts, however, no target should be given any
of these names.

- `c`, `psxgpu`, `psxgte`, `psxspu`, `psxcd`, `psxsio`, `psxetc`, `psxapi`, `lzp`
- `psn00bsdk_common`, `psn00bsdk_object_lib`
- `psn00bsdk_static_exe`
- `psn00bsdk_dynamic_exe`
- `psn00bsdk_static_lib`
- `psn00bsdk_shared_lib`, `psn00bsdk_module_lib`

## Commands

- `psn00bsdk_add_executable(<name> <STATIC|DYNAMIC> [EXCLUDE_FROM_ALL] [sources...])`

  A wrapper around `add_executable()` to create PS1 executables. Three files
  will be generated for each call to this function:

  - `<name>.elf` (regular ELF executable)
  - `<name>.exe` (executable converted to the format expected by the PS1)
  - `<name>.map` (symbol map file for dynamic linking/introspection)

  The `.exe` and `.map` extensions can be customized by overriding
  `PSN00BSDK_EXECUTABLE_SUFFIX` and `PSN00BSDK_SYMBOL_MAP_SUFFIX` prior to
  creating the executable.

  The second argument (mandatory) specifies whether the executable is going to
  load DLLs at runtime. If set to `STATIC`, $gp-relative addressing (i.e.
  reusing the $gp register normally used for DLL addressing) will be enabled,
  slightly reducing executable size and RAM usage but breaking compatibility
  with the dynamic linker.

- `psn00bsdk_add_library(<name> <STATIC|OBJECT|SHARED|MODULE> [EXCLUDE_FROM_ALL] [sources...])`

  Wraps `add_library()` to create static libraries or dynamically-linked
  libraries (DLLs).

  The second argument (mandatory, unlike `add_library()`) specifies the type of
  library to create. `STATIC` will create a static library named `lib<name>.a`.
  `SHARED` and `MODULE` will compile a DLL, producing the following files (note
  that there is no `lib` prefix for DLLs):

  - `<name>.so` (regular ELF shared library)
  - `<name>.dll` (raw binary with some ELF headers prepended)

  As with executables, the `.dll` extension can be customized by setting
  `PSN00BSDK_SHARED_LIBRARY_SUFFIX`.

- `psn00bsdk_add_cd_image(<name> <image name> <config file> [...])`

  Creates a new target that will build a CD image using `mkpsxiso`.

  The first argument is the name of the target to create; next up is the name
  of the generated image file (`<image name>.bin` + `<image name>.cue`). The
  third argument is the path to the XML file passed to `mkpsxiso`.

  The XML file is "configured" by CMake, i.e. any `${var}` or `@var@`
  expressions are replaced with the values of the respective variables. In
  particular `${CD_IMAGE_NAME}` is replaced with the second argument passed to
  `psn00bsdk_add_cd_image()`; the file must properly set the output file names
  like this:

  ```xml
  <?xml version="1.0" encoding="utf-8"?>
  <iso_project
    image_name="${CD_IMAGE_NAME}.bin"
    cue_sheet="${CD_IMAGE_NAME}.cue"
  >
  ```

  Any additional argument is passed through to the underlying call to
  `add_custom_target()`, so most of the options supported by
  `add_custom_target()` are also supported here.

## Definitions

When compiling executables and libraries using the above commands the following
preprocessor macros are automatically `#define`'d:

- `PLAYSTATION`

  Always set to 1. Can be used to implement different options or code paths for
  libraries, so they can target both the host and PS1 (as it won't be defined
  when compiling outside of the SDK).

- `DEBUG`

  Defined and set to 1 in a debug configuration, i.e. when the
  `CMAKE_BUILD_TYPE` variable is set to `Debug`. This value is used by the
  PSn00bSDK libraries, and should be used in executables, to enable additional
  debug logging.

  Note that the default CMake configuration is usually debug, so it's
  recommended to specify `-DCMAKE_BUILD_TYPE=Release` to get rid of the logging
  overhead in release builds and reduce executable size.

## Cached settings

These variables are stored in CMake's cache and can be edited by the project's
build script, from the CMake command line when configuring the project
(`-Dname=value`) or using an editor such as the CMake GUI.

- `PSN00BSDK_TARGET` (`STRING`)

  The GCC toolchain's target triplet. PSn00bSDK assumes the toolchain targets
  `mipsel-none-elf` by default, however this can be changed to e.g. use a MIPS
  toolchain that was compiled for a slightly-different-but-equivalent target.

  The following GCC target triplets have been confirmed to work with PSn00bSDK:

  - `mipsel-none-elf`
  - `mipsel-unknown-elf`
  - ~~`mipsel-linux-gnu`~~ (has issues with linking)

- `PSN00BSDK_TC` (`PATH`)

  Path to the GCC toolchain's installation prefix/directory. If not set, CMake
  will attempt to find the toolchain in the `PATH` environment variable and
  store its path in the project's variable cache (so the search does not have
  to be repeated). It is recommended to add the toolchain's `bin` subfolder to
  `PATH` rather than setting this variable.

  **IMPORTANT**: if the toolchain's target is not `mipsel-none-elf`,
  `PSN00BSDK_TARGET` must be set regardless of whether or not `PSN00BSDK_TC` is
  also set.

- `PSN00BSDK_LIBGCC` (`FILEPATH`)

  Path to the `libgcc.a` library bundled with the GCC toolchain. The contents
  of this library are merged into `libc` when building the SDK, so this
  variable is only actually needed when compiling `libpsn00b`. Setting this
  variable manually usually isn't necessary as CMake will locate `libgcc.a`
  automatically after finding the toolchain.

## Internal settings

These settings are not stored in CMake's cache and can only be set from within
the build script.

- `PSN00BSDK_LIBRARIES`

  List of libraries to link all created targets against. By default this
  includes all PSn00bSDK libraries.

- `PSN00BSDK_EXECUTABLE_SUFFIX`, `PSN00BSDK_SHARED_LIBRARY_SUFFIX`,
  `PSN00BSDK_SYMBOL_MAP_SUFFIX`

  File extensions to use for generated PS1 files. The default values are
  `.exe`, `.dll` and `.map` respectively. Note that file names and extensions
  can be changed anyway when building a CD image.

## Read-only variables

- `PSN00BSDK_VERSION`, `PSN00BSDK_BUILD_DATE`, `PSN00BSDK_GIT_TAG`,
  `PSN00BSDK_GIT_COMMIT`

  These variables are loaded from `lib/libpsn00b/build.json` and contain
  information about the SDK's version. Note that `PSN00BSDK_GIT_TAG` and
  `PSN00BSDK_GIT_COMMIT` are not populated by default when building PSn00bSDK
  manually from source, so they might be empty strings.

- `PSN00BSDK_TOOLS`, `PSN00BSDK_INCLUDE`, `PSN00BSDK_LDSCRIPTS`

  Lists of paths used internally. Should not be set, manipulated or overridden
  by scripts.

- `TOOLCHAIN_NM`

  Path to the `nm` executable used to generate symbol maps. Although not used
  internally by CMake, this program is part of the GCC toolchain.

- `ELF2X`, `ELF2CPE`, `MKPSXISO`, `LZPACK`, `SMXLINK`

  Paths to the PSn00bSDK tools' executables. As no functions are currently
  provided for building assets, `LZPACK` and `SMXLINK` can be used with
  `add_custom_command()`/`add_custom_target()` to convert models and generate
  LZP archives as part of the build pipeline.

-----------------------------------------
_Last updated on 2021-12-29 by spicyjpeg_