# How to Link Libraries in shadPS4-Emu Build: A Complete CMake Guide

> Learn how to link libraries in shadPS4-Emu CMake builds. Master internal and third-party dependency linking with this comprehensive guide for developers.

- Repository: [shadps4-emu/shadPS4](https://github.com/shadps4-emu/shadPS4)
- Tags: how-to-guide
- Published: 2026-03-19

---

**shadPS4 uses a centralized CMake configuration where internal libraries are source-file collections merged into the main executable, while third-party dependencies are discovered via `find_package` and linked through imported targets.**

Linking libraries correctly is essential when building or extending shadPS4, the open-source PlayStation 4 emulator. Whether you are adding a new core component or integrating an external dependency, understanding how to link libraries in shadps4-emu build processes ensures your changes compile and link properly with the rest of the codebase.

## Understanding the shadPS4 CMake Architecture

The emulator's build system is defined entirely in the top-level [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) at the repository root. This file handles three distinct categories of libraries: internal source collections, system dependencies, and vendored external code.

### Internal Libraries as Source Collections

Rather than creating separate static library targets for each component, shadPS4 groups source files into CMake variables. For example, the AJM (Audio Job Manager) library is defined as:

```cmake
set(AJM_LIB src/core/libraries/ajm/ajm.cpp
            src/core/libraries/ajm/ajm.h
            … )

```

These variables are concatenated into a master `CORE` list, which is then passed directly to `add_executable(shadps4 …)`. Because all sources compile into a single target, no explicit `target_link_libraries` call is required for internal components.

### Third-Party Dependencies via find_package

External system libraries are located using standard CMake `find_package` calls located around lines 120–150 of the root [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt):

```cmake
find_package(Boost 1.84.0 CONFIG)
find_package(CLI11 2.6.1 CONFIG)
find_package(FFmpeg 5.1.2 MODULE)
find_package(fmt 10.2.0 CONFIG)

```

When found, these create imported targets (e.g., `Boost::boost`, `fmt::fmt`) that CMake automatically links to the `shadps4` executable through the target's link interface.

### Vendored Libraries in externals/

Libraries that ship with the repository reside in the `externals/` directory. The top-level [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) includes them via:

```cmake
add_subdirectory(externals)

```

Each subdirectory contains its own [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) that defines a static library target (e.g., `gcn`). These targets are then added to the `CORE` variable or linked explicitly to the main executable.

## How to Link Internal Libraries in shadPS4

To add a new internal component, you extend the source collection pattern used throughout the project.

1. **Define a source variable** in the root [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) (place it near other library definitions):

   ```cmake
   set(FOO_LIB
       src/core/libraries/foo/foo.cpp
       src/core/libraries/foo/foo.h
       src/core/libraries/foo/foo_helper.cpp
       src/core/libraries/foo/foo_helper.h)
   ```

2. **Append to the CORE collection** (around line 250–260 where other libraries are merged):

   ```cmake
   set(CORE ${CORE}
       ${FOO_LIB})
   ```

3. **Regenerate the build files**:

   ```bash
   cmake -B build
   cmake --build build
   ```

The new sources compile and link automatically because they are part of the unified `shadps4` target.

## How to Link External Dependencies in shadPS4 Build

For system libraries or packages installed via a package manager, use the `find_package` + `target_link_libraries` pattern.

### Linking a Required System Package

Add the discovery and linking steps to the root [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt):

```cmake

# Near line 120-150 with other find_package calls

find_package(spdlog 1.12.0 CONFIG REQUIRED)

# After the add_executable(shadps4 ...) block

target_link_libraries(shadps4 PRIVATE spdlog::spdlog)

```

### Handling Optional Dependencies

For optional features like Discord RPC, wrap the logic in a conditional check:

```cmake
if (ENABLE_DISCORD_RPC)
    list(APPEND COMMON src/common/discord_rpc_handler.cpp 
                     src/common/discord_rpc_handler.h)
    find_package(discord-rpc CONFIG)
    target_link_libraries(shadps4 PRIVATE discord-rpc::discord-rpc)
endif()

```

This ensures the library only links when the corresponding CMake option is enabled.

## How to Add Vendored Libraries from externals/

When you need to include a library that must ship with the emulator source:

1. **Create the library directory** under `externals/mydep/` with its own [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt):

   ```cmake
   # externals/mydep/CMakeLists.txt

   add_library(mydep STATIC
       src/mydep.c
       src/mydep.h)
   
   target_include_directories(mydep PUBLIC 
       ${CMAKE_CURRENT_SOURCE_DIR}/src)
   ```

2. **Include the subdirectory** in the root [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) (around line 64 where other externals are added):

   ```cmake
   add_subdirectory(externals/mydep)
   ```

3. **Link the target** by appending it to the `CORE` variable or using `target_link_libraries`:

   ```cmake
   set(CORE ${CORE} mydep)
   # OR explicitly:

   target_link_libraries(shadps4 PRIVATE mydep)
   ```

## Summary

- **shadPS4** uses a monolithic CMake structure where the root [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) controls all linking.
- **Internal libraries** are collections of source files merged into the `CORE` variable; they require no explicit `target_link_libraries` because they compile directly into the `shadps4` executable.
- **System dependencies** are discovered via `find_package` and linked through imported targets like `fmt::fmt` or `Boost::boost`.
- **Vendored code** in `externals/` is built as static library subdirectories and linked via `add_subdirectory` and `target_link_libraries`.

## Frequently Asked Questions

### Where is the main CMakeLists.txt located in shadPS4?

The primary build configuration file resides at the repository root as [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt). This single file orchestrates all library linking, source collection, and target creation for the emulator.

### Do I need target_link_libraries for internal components?

No. Internal libraries in shadPS4 are implemented as CMake variables containing source file lists (e.g., `AJM_LIB`, `FOO_LIB`). These variables are appended to the master `CORE` list, which is passed directly to `add_executable(shadps4 …)`. Because the sources compile into the same target, no explicit linking command is required.

### How does shadPS4 handle optional dependencies like Discord RPC?

Optional features use CMake options (e.g., `ENABLE_DISCORD_RPC`). When enabled, the build system appends the relevant source files to the `COMMON` variable and calls `find_package` to locate the external library. The imported target (e.g., `discord-rpc::discord-rpc`) is then linked to the `shadps4` target using `target_link_libraries` inside the conditional block.

### Can I add system libraries using pkg-config instead of find_package?

While shadPS4 primarily uses `find_package` for dependency resolution, you can integrate `pkg-config` libraries by using CMake's `pkg_check_modules` command from the `FindPkgConfig` module. After locating the package, you would add the imported targets or compile/link flags to the `shadps4` target, following the same pattern used for the existing `find_package` dependencies.