openmoh / openmohaa

Open re-implementation of Medal of Honor: Allied Assault including Spearhead and Breakthrough expansions with modern features and bugfixes from ioquake3 with cross-platform support
https://www.openmohaa.org
GNU General Public License v2.0
378 stars 25 forks source link

cmake install does not install the game to expected filesystem locations on linux #526

Open joebonrichie opened 5 days ago

joebonrichie commented 5 days ago

invocation

cmake -B builddir -DCMAKE_INSTALL_PREFIX=/usr/; sudo ninja -C builddir install

locations

/usr/cgame.x86_64.so
/usr/launch_openmohaa_base.x86_64
/usr/launch_openmohaa_breakthrough.x86_64
/usr/launch_openmohaa_spearhead.x86_64
/usr/omohaaded.x86_64
/usr/openmohaa.x86_64
/usr/game.x86_64.so

expected locations

/usr/lib/openmohaa/cgame.x86_64.so
/usr/bin/launch_openmohaa_base.x86_64
/usr/bin/launch_openmohaa_breakthrough.x86_64
/usr/bin/launch_openmohaa_spearhead.x86_64
/usr/bin/omohaaded.x86_64
/usr/lib/openmohaa/openmohaa.x86_64
/usr/lib/openmohaa/game.x86_64.so

alternative locations

/usr/bin/launch_openmohaa_base.x86_64
/usr/bin/launch_openmohaa_breakthrough.x86_64
/usr/bin/launch_openmohaa_spearhead.x86_64
/usr/bin/omohaaded.x86_64
/usr/share/openmohaa/cgame.x86_64.so
/usr/share/openmohaa/game.x86_64.so
/usr/share/openmohaa/openmohaa.x86_64

Additionally, the TARGET_ARCH should not be suffixed when installing system-wide.

joebonrichie commented 5 days ago

I'm currently using this patch and things seem to be working. However, i'm unsure about other platforms.

From dec23c57132925ab167fa8249a2697590e766311 Mon Sep 17 00:00:00 2001
From: Joey Riches <josephriches@gmail.com>
Date: Tue, 19 Nov 2024 12:38:58 +0000
Subject: [PATCH 1/1] CMake: Support system-wide installation on linux

Not yet tested on other platforms
---
 CMakeLists.txt               |  4 ++--
 code/Launcher/CMakeLists.txt |  4 ++--
 code/cgame/CMakeLists.txt    |  5 ++---
 code/fgame/CMakeLists.txt    |  3 +--
 code/sys/new/sys_main_new.c  |  4 ++--
 code/sys/sys_main.c          | 12 +++++-------
 6 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index eb113f8d..59636d41 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -141,7 +141,7 @@ if (MSVC)
    INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION "./" OPTIONAL)
 endif()

-INSTALL(TARGETS omohaaded DESTINATION "./")
+INSTALL(TARGETS omohaaded DESTINATION ${EXECUTABLE_OUTPUT_PATH})

 if (NOT BUILD_NO_CLIENT)
    ## Client app
@@ -215,7 +215,7 @@ if (NOT BUILD_NO_CLIENT)
        INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION "./" OPTIONAL)
    endif()

-   INSTALL(TARGETS openmohaa DESTINATION "./")
+   INSTALL(TARGETS openmohaa DESTINATION ${EXECUTABLE_OUTPUT_PATH})
 endif()

 # Launcher
diff --git a/code/Launcher/CMakeLists.txt b/code/Launcher/CMakeLists.txt
index 68fa6abd..58ba350a 100644
--- a/code/Launcher/CMakeLists.txt
+++ b/code/Launcher/CMakeLists.txt
@@ -18,7 +18,7 @@ function (create_launcher name type)
     target_compile_features(openmohaa_launcher_${name} PRIVATE cxx_std_17)
     set_target_properties(openmohaa_launcher_${name} PROPERTIES OUTPUT_NAME "launch_openmohaa_${name}${TARGET_BIN_SUFFIX}")

-    INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION "./")
+    INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION ${EXECUTABLE_OUTPUT_PATH})

     #add_executable(omohaaded_launcher_${name} ${LAUNCHER_SOURCES})
     #target_include_directories(omohaaded_launcher_${name} PUBLIC "../qcommon")
@@ -26,7 +26,7 @@ function (create_launcher name type)
     #target_compile_features(omohaaded_launcher_${name} PRIVATE cxx_std_17)
     #set_target_properties(omohaaded_launcher_${name} PROPERTIES OUTPUT_NAME "launch_omohaaded_${name}${TARGET_BIN_SUFFIX}")
     #
-    #INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION "./")
+    #INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
 endfunction()

 create_launcher(base 0)
diff --git a/code/cgame/CMakeLists.txt b/code/cgame/CMakeLists.txt
index fd6974b8..9de3f6fe 100644
--- a/code/cgame/CMakeLists.txt
+++ b/code/cgame/CMakeLists.txt
@@ -33,10 +33,9 @@ set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_G

 INSTALL(
    TARGETS cgame
-   LIBRARY DESTINATION "${TARGET_BASE_GAME}"
-   RUNTIME DESTINATION "${TARGET_BASE_GAME}"
+   LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 )

 if(MSVC)
    INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL)
-endif()
\ No newline at end of file
+endif()
diff --git a/code/fgame/CMakeLists.txt b/code/fgame/CMakeLists.txt
index 35524cd6..d17bb492 100644
--- a/code/fgame/CMakeLists.txt
+++ b/code/fgame/CMakeLists.txt
@@ -72,8 +72,7 @@ set_target_properties(fgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_G

 INSTALL(
    TARGETS fgame
-   LIBRARY DESTINATION "${TARGET_BASE_GAME}"
-   RUNTIME DESTINATION "${TARGET_BASE_GAME}"
+   LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 )

 if(MSVC)
diff --git a/code/sys/new/sys_main_new.c b/code/sys/new/sys_main_new.c
index cc03d144..22822244 100644
--- a/code/sys/new/sys_main_new.c
+++ b/code/sys/new/sys_main_new.c
@@ -241,7 +241,7 @@ void* Sys_GetGameAPI(void* parms)
     if (game_library)
         Com_Error(ERR_FATAL, "Sys_GetGameAPI without calling Sys_UnloadGame");

-    game_library = Sys_LoadDll(gamename, qfalse);
+    game_library = Sys_LoadDll(gamename, qtrue);

     //Still couldn't find it.
     if (!game_library) {
@@ -290,7 +290,7 @@ void* Sys_GetCGameAPI(void* parms)
     if (cgame_library)
         Com_Error(ERR_FATAL, "Sys_GetCGameAPI without calling Sys_UnloadCGame");

-    cgame_library = Sys_LoadDll(gamename, qfalse);
+    cgame_library = Sys_LoadDll(gamename, qtrue);

     //Still couldn't find it.
     if (!cgame_library) {
diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c
index 15518c49..b00968b3 100644
--- a/code/sys/sys_main.c
+++ b/code/sys/sys_main.c
@@ -505,7 +505,7 @@ void *Sys_LoadDll(const char *name, qboolean useSystemLib)
        Com_Printf("Trying to load \"%s\"...\n", name);
        dllhandle = Sys_LoadLibrary(name);
    }
-   
+
    if(!dllhandle)
    {
        const char *topDir;
@@ -531,10 +531,10 @@ void *Sys_LoadDll(const char *name, qboolean useSystemLib)
        if(!dllhandle)
        {
            const char *basePath = Cvar_VariableString("fs_basepath");
-           
+
            if(!basePath || !*basePath)
                basePath = ".";
-           
+
            if(FS_FilenameCompare(topDir, basePath))
            {
                len = Com_sprintf(libPath, sizeof(libPath), "%s%c%s", basePath, PATH_SEP, name);
@@ -548,12 +548,12 @@ void *Sys_LoadDll(const char *name, qboolean useSystemLib)
                    Com_Printf("Skipping trying to load \"%s\" from \"%s\", file name is too long.\n", name, basePath);
                }
            }
-           
+
            if(!dllhandle)
                Com_Printf("Loading \"%s\" failed\n", name);
        }
    }
-   
+
    return dllhandle;
 }

@@ -810,7 +810,6 @@ int main( int argc, char **argv )
 #endif

    Sys_ParseArgs( argc, argv );
-   Sys_SetBinaryPath( Sys_Dirname( argv[ 0 ] ) );
    Sys_SetDefaultInstallPath( DEFAULT_BASEDIR );

    // Concatenate the command line for passing to Com_Init
@@ -874,4 +873,3 @@ int main( int argc, char **argv )

    return 0;
 }
-
-- 
2.47.0

With the file locations being

<Path fileType="executable">/usr/bin/launch_openmohaa_base.x86_64</Path>
<Path fileType="executable">/usr/bin/launch_openmohaa_breakthrough.x86_64</Path>
<Path fileType="executable">/usr/bin/launch_openmohaa_spearhead.x86_64</Path>
<Path fileType="executable">/usr/bin/omohaaded.x86_64</Path>
<Path fileType="executable">/usr/bin/openmohaa.x86_64</Path>
<Path fileType="library">/usr/lib/cgame.x86_64.so</Path>
<Path fileType="library">/usr/lib/game.x86_64.so</Path>
<Path fileType="data">/usr/share/applications/org.openmoh.openmohaa.desktop</Path>
<Path fileType="data">/usr/share/applications/org.openmoh.openmohaab.desktop</Path>
<Path fileType="data">/usr/share/applications/org.openmoh.openmohaas.desktop</Path>
<Path fileType="data">/usr/share/icons/hicolor/symbolic/apps/org.openmoh.openmohaa.svg</Path>
<Path fileType="data">/usr/share/metainfo/org.openmoh.openmohaa.metainfo.xml</Path>
smallmodel commented 5 days ago

Wouldn't it be ideal to store it in /usr/local/games/openmohaa? For example, ioquake3 default installation directory is in /usr/local/games/quake3 without bin/lib folder, the engine currently only looks for shared libraries in the root directory However it means setting the install prefix which is incompatible with the location of desktop entries

joebonrichie commented 5 days ago

I suppose /usr/local/games is part of the FHS and would be a suitable location for a user compiling on their own or as a location to install the precompiled tarball to. To be clear, I am coming from the angle of eventually getting openmohaa packaged up in Solus when it's ready, as we have other projects similar to this packaged such as openmw where the user needs to provide the original game assets.

Enabling useSystemlib when calling Sys_LoadDll() allows openmohaa to load cgame.so/game.so from the /usr/lib location which should be suitable for a system package. I assume /usr/lib/openmohaa/cgame.so, /usr/lib/openmohaa/game.so will also work with useSystemlib enabled but haven't tested that yet.

smallmodel commented 5 days ago

I tested and unfortunately the loader doesn't look recursively in folders inside /usr/lib.

Can CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBDIR both be set to bin/openmohaa when packaging? I'm aware that libraries would be stored in a non-standard directory even though those libs can only be used by openmohaa. Otherwise this would require some core changes that would deviate from upstream (ioquake3). Other solutions: add a configuration file in /etc/ld.so.conf.d/ (automatically), or append /usr/lib/openmohaa in $LD_LIBRARY_PATH from the .desktop file

The CMake arguments would be: -DCMAKE_INSTALL_BINDIR="bin/openmohaa" -DCMAKE_INSTALL_LIBDIR="bin/openmohaa" -DCMAKE_INSTALL_PREFIX=/usr

joebonrichie commented 4 days ago

i think subdirectories in /usr/bin is invalid, having the libs side by side for a pre-compiled tarball is still totally fine of course. I've adjusted the patch and i'm using for a system-wide installation:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 58551cc1..d3f1b350 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,6 @@ option(USE_INTERNAL_ZLIB "If set, use bundled zlib."    ${USE_INTERNAL_LIBS})

 # Installation directory
 set(CMAKE_INSTALL_BINDIR bin CACHE PATH "Binary dir")
-set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Library dir")
 include(GNUInstallDirs)

 if(TARGET_GAME_TYPE)
@@ -236,4 +235,3 @@ if(NOT TARGET uninstall)
   add_custom_target(uninstall
     COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
 endif()
-
diff --git a/code/cgame/CMakeLists.txt b/code/cgame/CMakeLists.txt
index 1f6ef8ed..302f6c84 100644
--- a/code/cgame/CMakeLists.txt
+++ b/code/cgame/CMakeLists.txt
@@ -28,10 +28,10 @@ target_compile_features(cgame PUBLIC c_variadic_macros)
 target_link_libraries(cgame PUBLIC qcommon)

 set_target_properties(cgame PROPERTIES PREFIX "")
-set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_BIN_SUFFIX}")
+set_target_properties(cgame PROPERTIES OUTPUT_NAME "openmohaa_cgame${TARGET_BIN_SUFFIX}")

 INSTALL(TARGETS cgame)

 if(MSVC)
    INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION bin OPTIONAL)
-endif()
\ No newline at end of file
+endif()
diff --git a/code/fgame/CMakeLists.txt b/code/fgame/CMakeLists.txt
index 950ac59e..c8383c90 100644
--- a/code/fgame/CMakeLists.txt
+++ b/code/fgame/CMakeLists.txt
@@ -67,7 +67,7 @@ target_compile_features(fgame PUBLIC c_variadic_macros)
 target_link_libraries(fgame PUBLIC qcommon)

 set_target_properties(fgame PROPERTIES PREFIX "")
-set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_BIN_SUFFIX}")
+set_target_properties(fgame PROPERTIES OUTPUT_NAME "openmohaa_game${TARGET_BIN_SUFFIX}")

 INSTALL(TARGETS fgame)

diff --git a/code/sys/new/sys_main_new.c b/code/sys/new/sys_main_new.c
index cc03d144..5b7581b9 100644
--- a/code/sys/new/sys_main_new.c
+++ b/code/sys/new/sys_main_new.c
@@ -236,12 +236,12 @@ Sys_GetGameAPI
 void* Sys_GetGameAPI(void* parms)
 {
     void* (*GetGameAPI) (void*);
-    const char* gamename = "game" "." ARCH_STRING DLL_SUFFIX DLL_EXT;
+    const char* gamename = "openmohaa_game" "." ARCH_STRING DLL_SUFFIX DLL_EXT;

     if (game_library)
         Com_Error(ERR_FATAL, "Sys_GetGameAPI without calling Sys_UnloadGame");

-    game_library = Sys_LoadDll(gamename, qfalse);
+    game_library = Sys_LoadDll(gamename, qtrue);

     //Still couldn't find it.
     if (!game_library) {
@@ -285,12 +285,12 @@ Sys_GetCGameAPI
 void* Sys_GetCGameAPI(void* parms)
 {
     void* (*GetCGameAPI) (void*);
-    const char* gamename = "cgame" "." ARCH_STRING DLL_SUFFIX DLL_EXT;
+    const char* gamename = "openmohaa_cgame" "." ARCH_STRING DLL_SUFFIX DLL_EXT;

     if (cgame_library)
         Com_Error(ERR_FATAL, "Sys_GetCGameAPI without calling Sys_UnloadCGame");

-    cgame_library = Sys_LoadDll(gamename, qfalse);
+    cgame_library = Sys_LoadDll(gamename, qtrue);

     //Still couldn't find it.
     if (!cgame_library) {
-- 
2.47.0

which gives

            <Path fileType="executable">/usr/bin/launch_openmohaa_base.x86_64</Path>
            <Path fileType="executable">/usr/bin/launch_openmohaa_breakthrough.x86_64</Path>
            <Path fileType="executable">/usr/bin/launch_openmohaa_spearhead.x86_64</Path>
            <Path fileType="executable">/usr/bin/omohaaded.x86_64</Path>
            <Path fileType="executable">/usr/bin/openmohaa.x86_64</Path>
            <Path fileType="library">/usr/lib/openmohaa_cgame.x86_64.so</Path>
            <Path fileType="library">/usr/lib/openmohaa_game.x86_64.so</Path>

with the libs being more descriptive they should be fine to live in the lib dir. I'm also considering that placing everything apart from the launchers in /usr/lib/openmohaa may also be suitable, as that's how applications like firefox do it, e.g.

/usr/bin/launch_openmohaa_base
/usr/bin/launch_openmohaa_breakthrough
/usr/bin/launch_openmohaa_spearhead
/usr/lib/openmohaa/openmohaa
/usr/lib/openmohaa/omohaaded
/usr/lib/openmohaa/cgame.so
/usr/lib/openmohaa/game.so

The downside of this is that the server bin would no longer live in $PATH and the launchers would need to learn to look in the lib dir. Alternatively, everything could live in /usr/lib/openmohaa and the launchers and the dedi-server bin could be symlinked to /usr/bin

smallmodel commented 4 days ago

Even /usr/games (which is correct from FHS) is not allowed? Binaries and shared libraries will be in /usr/lib/openmohaa, and symlinks will be created in /usr/bin. It will just need to be cross-platform (checking UNIX should be enough) and be compatible with custom folders/prefix, will research.

Can you point to the documentation resources listing allowed directories? I only found this

joebonrichie commented 4 days ago

here is the official fhs spec https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html

smallmodel commented 4 days ago

All bins will be in /usr/lib/openmohaa, like in ioquake3

smallmodel commented 4 days ago

The CMake install was modified, clear cache and let me know if you encounter any issues (no symlink yet)