Module: MilkTea::Steamworks

Defined in:
lib/milk_tea/bindings/steamworks.rb

Defined Under Namespace

Classes: Error, Generator

Constant Summary collapse

SOURCE_NAME =
"steamworks_sdk"
HELPER_HEADER_BASENAME =
"steamworks.h"
SDK_ROOT_ENV_VAR =
"STEAMWORKS_SDK_ROOT"
API_JSON_ENV_VAR =
"STEAMWORKS_API_JSON"
API_JSON_RELATIVE_PATH =
"public/steam/steam_api.json"
REDISTRIBUTABLE_DIRECTORY_BY_PLATFORM =
{
  linux: "redistributable_bin/linux64",
  darwin: "redistributable_bin/osx",
  windows: "redistributable_bin/win64",
}.freeze
{
  linux: "steam_api",
  darwin: "steam_api",
  windows: "steam_api64",
}.freeze
IMPORT_LIBRARY_BASENAME_BY_PLATFORM =
{
  linux: "libsteam_api.so",
  darwin: "libsteam_api.dylib",
  windows: "steam_api64.lib",
}.freeze
RUNTIME_LIBRARY_BASENAME_BY_PLATFORM =
{
  linux: "libsteam_api.so",
  darwin: "libsteam_api.dylib",
  windows: "steam_api64.dll",
}.freeze

Class Method Summary collapse

Class Method Details

.api_json_path(root: MilkTea.root, env: ENV, bootstrap: false) ⇒ Object

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/milk_tea/bindings/steamworks.rb', line 79

def api_json_path(root: MilkTea.root, env: ENV, bootstrap: false)
  explicit_path = env[API_JSON_ENV_VAR]
  if explicit_path && !explicit_path.empty?
    candidate = Pathname.new(File.expand_path(explicit_path))
    return candidate if File.file?(candidate)

    raise Error, "Steamworks metadata not found: #{candidate}"
  end

  resolved_sdk_root = sdk_root(root:, env:, bootstrap:)
  return unless resolved_sdk_root

  candidate = resolved_sdk_root.join(API_JSON_RELATIVE_PATH)
  return candidate if File.file?(candidate)

  raise Error, "Steamworks metadata not found under #{resolved_sdk_root}"
end


56
57
58
# File 'lib/milk_tea/bindings/steamworks.rb', line 56

def default_link_libraries(platform: host_platform)
  [LINK_LIBRARY_NAME_BY_PLATFORM.fetch(platform)]
end

.helper_header_path(root: MilkTea.root) ⇒ Object



43
44
45
# File 'lib/milk_tea/bindings/steamworks.rb', line 43

def helper_header_path(root: MilkTea.root)
  root.join("std/c/#{HELPER_HEADER_BASENAME}")
end

.host_platformObject



52
53
54
# File 'lib/milk_tea/bindings/steamworks.rb', line 52

def host_platform
  MilkTea.host_platform
end

.import_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/milk_tea/bindings/steamworks.rb', line 107

def import_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
  directory = redistributable_directory(root:, env:, platform:, bootstrap:)
  return unless directory

  candidate = directory.join(IMPORT_LIBRARY_BASENAME_BY_PLATFORM.fetch(platform))
  return candidate if File.file?(candidate)

  nil
end

.prepare!(root: MilkTea.root, env: ENV) ⇒ Object

Raises:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/milk_tea/bindings/steamworks.rb', line 127

def prepare!(root: MilkTea.root, env: ENV)
  path = helper_header_path(root:)
  existing = File.exist?(path)
  json_path = api_json_path(root:, env:, bootstrap: !existing)
  return path.to_s if json_path.nil? && existing
  raise Error, "Steamworks metadata unavailable; set #{API_JSON_ENV_VAR} or #{SDK_ROOT_ENV_VAR}" unless json_path

  generated = Generator.new(json_path:).generate
  FileUtils.mkdir_p(path.dirname)
  return path.to_s if existing && File.read(path) == generated

  File.write(path, generated)
  path.to_s
end

.redistributable_directory(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false) ⇒ Object



97
98
99
100
101
102
103
104
105
# File 'lib/milk_tea/bindings/steamworks.rb', line 97

def redistributable_directory(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
  resolved_sdk_root = sdk_root(root:, env:, bootstrap:)
  return unless resolved_sdk_root

  directory = resolved_sdk_root.join(REDISTRIBUTABLE_DIRECTORY_BY_PLATFORM.fetch(platform))
  return directory if File.directory?(directory)

  nil
end

.runtime_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false) ⇒ Object



117
118
119
120
121
122
123
124
125
# File 'lib/milk_tea/bindings/steamworks.rb', line 117

def runtime_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
  directory = redistributable_directory(root:, env:, platform:, bootstrap:)
  return unless directory

  candidate = directory.join(RUNTIME_LIBRARY_BASENAME_BY_PLATFORM.fetch(platform))
  return candidate if File.file?(candidate)

  nil
end

.sdk_root(root: MilkTea.root, env: ENV, bootstrap: false) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/milk_tea/bindings/steamworks.rb', line 60

def sdk_root(root: MilkTea.root, env: ENV, bootstrap: false)
  candidates = []
  env_root = env[SDK_ROOT_ENV_VAR]
  candidates << canonical_sdk_root(env_root) if env_root && !env_root.empty?

  third_party_sdk = MilkTea.data_root.join("third_party/steamworks-sdk")
  candidates << canonical_sdk_root(third_party_sdk) if File.directory?(third_party_sdk)

  upstream_root = source(root:).checkout_root
  candidates << canonical_sdk_root(upstream_root) if File.directory?(upstream_root)

  if bootstrap && candidates.none? { |path| sdk_layout_present?(path) }
    source(root:).bootstrap!
    candidates << canonical_sdk_root(upstream_root)
  end

  candidates.find { |path| sdk_layout_present?(path) }
end

.source(root: MilkTea.root) ⇒ Object



47
48
49
50
# File 'lib/milk_tea/bindings/steamworks.rb', line 47

def source(root: MilkTea.root)
  UpstreamSources.default_sources(root:).find { |entry| entry.name == SOURCE_NAME } ||
    raise(Error, "missing upstream source definition for #{SOURCE_NAME}")
end