# `CauldronGPU.Setup`
[🔗](https://github.com/jaman/cauldron/blob/v0.3.3/cauldron_gpu/lib/cauldron_gpu/setup.ex#L1)

What building the renderer needs on this machine, and the build configuration
`mix cauldron_gpu.setup` writes.

Each platform module (`CauldronGPU.Setup.MacOS`, `CauldronGPU.Setup.Linux`,
`CauldronGPU.Setup.Windows`) implements `CauldronGPU.Setup.Platform`: it looks for each
thing the build needs in that platform's usual places, installs what it can, and turns
what it found into configuration.

The configuration is `build.config` in `:filename.basedir(:user_config, "cauldron_gpu")`,
Erlang terms read with `:file.consult/1`. `mix.exs` passes it to `make` or `nmake`:

  * `{choice, card | software}`: `software` builds no renderer
  * `{pkg_config, Path}`: `PKG_CONFIG`, the `pkg-config` program
  * `{pkg_config_path, Path}`: added to `PKG_CONFIG_PATH`
  * `{sdl3_dir, Path}`: `SDL3_DIR`, an SDL3 development folder (Windows)
  * `{vulkan_include, Path}`: `VULKAN_INCLUDE`, the folder holding `vulkan/vulkan.hpp`
  * `{msvc_env, [{Name, Value}]}`: the environment MSVC's `vcvars64.bat` sets, used when
    `cl` is not already on `PATH`
  * `{nmake, Path}`: MSVC's `nmake.exe`, used when `nmake` is not on `PATH`

Other variables already set in the environment take precedence over the file.

# `item`

```elixir
@type item() :: %{
  key: atom(),
  name: String.t(),
  required?: boolean(),
  found: String.t() | nil,
  install: String.t() | nil,
  manual: String.t()
}
```

One thing the build needs:

  * `key`: the platform's name for it
  * `name`: what to call it when talking to a person
  * `required?`: whether the renderer can be built without it
  * `found`: where it is, or `nil`
  * `install`: what the automatic install does, or `nil` when it cannot be automated
  * `manual`: how a person installs it themselves

# `build_env`

```elixir
@spec build_env(map()) :: [{String.t(), String.t()}]
```

The environment variables `config` sets for the build, as `mix.exs` passes them; set in
this process before rebuilding, so the build that follows uses them.

# `cache_dir`

```elixir
@spec cache_dir() :: Path.t()
```

The folder downloads and builds go into.

# `card_status`

```elixir
@spec card_status() :: {:ok, String.t(), [atom()]} | {:error, String.t()}
```

Whether games can draw on the graphics card: `{:ok, device, backends}` when the renderer
loads and opens an offscreen device, else `{:error, text}` saying why. Loads the
renderer again first, so a build made since this process started is the one checked.

# `config_path`

```elixir
@spec config_path() :: Path.t()
```

The configuration file's path.

# `platform`

```elixir
@spec platform() :: module()
```

The platform module for the machine this runs on.

# `read_config`

```elixir
@spec read_config() :: map()
```

The configuration written last, or `%{}`.

# `sdl3_version`

```elixir
@spec sdl3_version() :: String.t()
```

The SDL3 release downloaded when SDL3 is fetched rather than installed.

# `vulkan_headers_version`

```elixir
@spec vulkan_headers_version() :: String.t()
```

The Vulkan-Headers release downloaded when Vulkan's headers are missing.

# `write_config`

```elixir
@spec write_config(map()) :: :ok
```

Writes `config` as the configuration, replacing the file.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
