Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ out

/game/neo/screenshots

# Mod launcher binary and the appid file it writes at runtime
/game/neo_linux64
/game/steam_appid.txt

# Binary Assets
/game/**/bin/**
/game/neo/maps
Expand Down
8 changes: 8 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ option(NEO_USE_SEPARATE_BUILD_INFO "Use separate build info on Linux" OFF)
option(NEO_ENABLE_CPACK "Enable CPack" OFF)
option(NEO_USE_MEM_DEBUG "Enable USE_MEM_DEBUG defines" OFF)
option(NEO_GENERATE_GAMEDATA "Generate SourceMod gamedata" ${NEO_DEDICATED})
option(NEO_BUILD_LAUNCHER "Build the Steam mod launcher" OFF) # NOTE Linux only

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why OFF by default?

set(NEO_MOD_APPID "" CACHE STRING "Steam appid for the mod launcher's steam_appid.txt")

message(STATUS "Treat compile warnings as errors: ${CMAKE_COMPILE_WARNING_AS_ERROR}")
message(STATUS "CI build mode: ${NEO_CI_BUILD}")
Expand All @@ -74,6 +76,8 @@ message(STATUS "Install game libraries: ${NEO_INSTALL_LIBRARIES}")
message(STATUS "Install game resources: ${NEO_INSTALL_RESOURCES}")
message(STATUS "Use separate build info on Linux: ${NEO_USE_SEPARATE_BUILD_INFO}")
message(STATUS "Enable CPack: ${NEO_ENABLE_CPACK}")
message(STATUS "Build the Steam mod launcher: ${NEO_BUILD_LAUNCHER}")
message(STATUS "Mod launcher appid override: ${NEO_MOD_APPID}")
message("")

if(NEO_COPY_LIBRARIES)
Expand Down Expand Up @@ -452,6 +456,10 @@ endif()

add_subdirectory(game/server)

if(NEO_BUILD_LAUNCHER AND OS_LINUX AND NOT NEO_DEDICATED)
add_subdirectory(launcher_main)
endif()

if(NEO_COPY_LIBRARIES)
set(COPY_ALL_LIBS_FLAG ALL)
else()
Expand Down
60 changes: 60 additions & 0 deletions src/launcher_main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Steam mod launcher (Linux). Valve's prebuilt Linux launcher never sets
# SDK_EXEC_DIR before exec'ing hl2.sh, so relative SDK search paths in
# gameinfo.txt silently fail to mount on standalone (non-sourcemods) installs.
# So we build it ourselves.
find_package(SDL2 REQUIRED)

add_executable(launcher_main
main.cpp
)

# GetExecutableModName derives the default -game dir from the executable name
# by stripping from the last underscore: neo_linux64 -> -game neo. The suffix
# also avoids colliding with the game/neo directory at the install root.
set_target_properties(launcher_main
PROPERTIES
OUTPUT_NAME neo_linux64
)

target_include_directories(launcher_main
PRIVATE
${CMAKE_SOURCE_DIR}/public
${CMAKE_SOURCE_DIR}/common
)

target_link_libraries(launcher_main
PRIVATE
SDL2::SDL2
${CMAKE_DL_LIBS}
)

# main.cpp defines __wrap_fopen/__wrap_fopen64 which reference __real_fopen/__real_fopen64
target_link_options(launcher_main
PRIVATE
-Wl,--wrap=fopen
-Wl,--wrap=fopen64
)

if(NEO_MOD_APPID)
target_compile_definitions(launcher_main
PRIVATE
MOD_LAUNCHER
MOD_APPID=${NEO_MOD_APPID}
)
endif()

if(NEO_COPY_LIBRARIES)
# Stage the standalone-install layout: launcher at the install root next to
# neo/, and the steam_api lib where the launcher dlopens it.
add_custom_command(TARGET launcher_main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:launcher_main>
${CMAKE_SOURCE_DIR}/../game/
COMMAND ${CMAKE_COMMAND} -E make_directory
${CMAKE_SOURCE_DIR}/../game/bin/linux64
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_SOURCE_DIR}/lib/public/linux64/libsteam_api.so
${CMAKE_SOURCE_DIR}/../game/bin/linux64/
VERBATIM
)
endif()
10 changes: 9 additions & 1 deletion src/launcher_main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <dlfcn.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#define MAX_PATH PATH_MAX
#endif

Expand Down Expand Up @@ -47,6 +48,7 @@ extern "C" { __declspec( dllexport ) int AmdPowerXpressRequestHighPerformance =
#endif


#include "tier1/strtools.h" // matchmakingtypes.h (via steam_api.h) uses V_strcpy_safe
#include <steam/steam_api.h>

#ifdef _WIN32
Expand Down Expand Up @@ -627,6 +629,10 @@ int main( int argc, char *argv[] )
return 1;
}

// Tell the engine where the SDK Base install lives so FileSystem_LoadSearchPaths
// resolves relative SDK mounts against it. Same thing the Windows path does above.
setenv( "SDK_EXEC_DIR", szGameInstallDir, 1 );

char szExecutable[8192];
snprintf(szExecutable, sizeof(szExecutable), "%s/hl2.sh", szGameInstallDir );

Expand Down Expand Up @@ -662,7 +668,9 @@ int main( int argc, char *argv[] )

execvp( szExecutable, new_argv.data() );

return 0;
// execvp only returns on failure
fprintf( stderr, "[Source Mod Launcher] Failed to exec %s: %s\n", szExecutable, strerror( errno ) );
return 1;
}

#else
Expand Down