Restructure bin/: deployables at root, tests and tools in subfolders

Only the shipping artifacts (coop_host.exe, coop_hook.dll, coop_hook_x86.dll,
coop_inject_x86.exe, steam_api64.dll, steam_input_actions.vdf) now land in the
bin/<config>/ root, so it can be copied wholesale into a donor game folder. Test
exes (plus the coop_tone fixture) build into bin/<config>/tests/ and the dev probes
into bin/<config>/tools/, via a new coop_output_subdir() CMake helper.

The probes resolve coop_hook.dll / the x86 injector from the deployable root one
level up (new common/coop/tool_paths.hpp: deployed_artifact_path checks next-to-exe
then parent). coop_tone is co-located with the tests so audio_loopback_test's
"spawn coop_tone.exe next to me" lookup is unchanged.

Verified from a clean bin/: root holds only deployables; ctest x64 7/7 and x86 3/3
green (incl. audio_loopback_test driving coop_tone from tests/).

Also convert the roadmap Planned list to bullets and drop this (now-done) item.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 00:59:03 +02:00
parent e9d1253b8f
commit 61049a620c
10 changed files with 223 additions and 174 deletions

View File

@@ -0,0 +1,52 @@
// Resolve artifacts that ship in the deployable bin/<config>/ root even when the
// running executable lives in a sibling subfolder (e.g. dev tools staged under
// bin/<config>/tools/). The probes use this to find coop_hook.dll and the x86
// injector helper, which stay at the root while the probes themselves do not.
#pragma once
#include <cstddef>
#include <string>
#include <windows.h>
namespace coop
{
// Directory of the current executable, with a trailing separator.
inline std::wstring exe_directory()
{
wchar_t buf[MAX_PATH] = {};
GetModuleFileNameW(nullptr, buf, MAX_PATH);
std::wstring path(buf);
const std::size_t slash = path.find_last_of(L"\\/");
return slash == std::wstring::npos ? std::wstring() : path.substr(0, slash + 1);
}
// Full path to a deployed artifact `name`: prefer one next to the running exe, else
// one directory up (the deployable root, when the exe runs from a tools/ subfolder).
// Falls back to the next-to-exe path so callers can report a sensible "not found".
inline std::wstring deployed_artifact_path(const wchar_t* name)
{
const std::wstring here = exe_directory() + name;
if (GetFileAttributesW(here.c_str()) != INVALID_FILE_ATTRIBUTES)
{
return here;
}
std::wstring dir = exe_directory();
if (!dir.empty())
{
dir.pop_back(); // drop the trailing separator before going up a level
}
const std::size_t slash = dir.find_last_of(L"\\/");
if (slash != std::wstring::npos)
{
const std::wstring up = dir.substr(0, slash + 1) + name;
if (GetFileAttributesW(up.c_str()) != INVALID_FILE_ATTRIBUTES)
{
return up;
}
}
return here;
}
} // namespace coop