Skip to content
Snippets Groups Projects
Commit fa50421c authored by Simon McVittie's avatar Simon McVittie
Browse files

Detect which architectures we can run by running a helper executable

parent 016975c2
No related branches found
No related tags found
1 merge request!1WIP: Initial code-drop for review
......@@ -57,6 +57,21 @@ Description: Steam Runtime utility library - shared library
.
This package contains the shared library.
Package: libsteam-runtime-tools-0-helpers
Architecture: amd64 i386
Multi-Arch: same
Section: misc
Depends:
${misc:Depends},
${shlibs:Depends},
Description:
The Steam Runtime is the library stack used to run the Steam client
on Linux. The Steam Runtime Tools utility library contains open-source
supporting code used by the Steam client to discover system information.
.
This package contains helper tools used to examine the library stack
available for each architecture.
Package: libsteam-runtime-tools-0-tests
Architecture: any
Section: misc
......
usr/libexec/steam-runtime-tools-0/*
# Copyright © 2019 Collabora Ltd.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
executable(
multiarch + '-true',
'true.c',
install : true,
install_dir : join_paths(
get_option('libexecdir'),
'steam-runtime-tools-' + api_major,
)
)
# vim:set sw=2 sts=2 et:
/*
* Copyright © 2019 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* This is basically /bin/true. We have it so that we can compile it for
* multiple CPU architectures, and check which ones we can run.
*/
int
main (int argc,
char **argv)
{
return 0;
}
......@@ -103,7 +103,20 @@ gobject = dependency(
)
project_include_dirs = include_directories('.')
if host_machine.cpu_family() == 'x86_64'
multiarch = 'x86_64-linux-gnu'
elif host_machine.cpu_family() == 'x86'
multiarch = 'i386-linux-gnu'
else
multiarch = ''
endif
subdir('steam-runtime-tools')
if multiarch != ''
subdir('helpers')
endif
subdir('docs')
subdir('examples')
subdir('tests')
......
......@@ -25,24 +25,136 @@
#include "steam-runtime-tools/architecture.h"
#include <dlfcn.h>
#include <link.h>
#include <string.h>
static gchar *helpers_path = NULL;
static const char *
_srt_get_helpers_path (void)
{
const char *path;
void *handle = NULL;
struct link_map *map = NULL;
path = helpers_path;
if (path != NULL)
goto out;
path = g_getenv ("SRT_HELPERS_PATH");
if (path != NULL)
goto out;
handle = dlopen (NULL, RTLD_LAZY|RTLD_GLOBAL);
if (handle == NULL)
{
g_warning ("Unable to dlopen self: %s", dlerror ());
goto out;
}
if (dlinfo (handle, RTLD_DI_LINKMAP, &map) != 0)
{
g_warning ("dlinfo RTLD_DI_LINKMAP: %s", dlerror ());
goto out;
}
while (map != NULL && map->l_prev != NULL)
map = map->l_prev;
for (; map != NULL; map = map->l_next)
{
g_debug ("%s", map->l_name);
if (g_str_has_suffix (map->l_name, "/" _SRT_SONAME))
{
gchar *dir = g_path_get_dirname (map->l_name);
if (g_str_has_suffix (dir, "/" _SRT_MULTIARCH))
dir[strlen (dir) - strlen ("/" _SRT_MULTIARCH)] = '\0';
if (g_str_has_suffix (dir, "/lib"))
dir[strlen (dir) - strlen ("/lib")] = '\0';
/* deliberate one-per-process leak */
helpers_path = g_build_filename (
dir, "libexec", "steam-runtime-tools-" _SRT_API_MAJOR,
NULL);
path = helpers_path;
g_free (dir);
break;
}
}
out:
if (handle != NULL)
dlclose (handle);
/* We have to return *something* non-NULL */
if (path == NULL)
{
g_warning ("Unable to determine path to helpers");
path = "/";
}
return path;
}
static gboolean
_srt_architecture_can_run (const char *multiarch)
{
gchar *helper = NULL;
const gchar *argv[] = { "true", NULL };
int exit_status = -1;
GError *error = NULL;
gboolean ret = FALSE;
helper = g_strdup_printf ("%s/%s-true",
_srt_get_helpers_path (), multiarch);
argv[0] = helper;
g_debug ("Testing architecture %s with %s", multiarch, helper);
if (!g_spawn_sync (NULL, /* working directory */
(gchar **) argv,
NULL, /* envp */
0, /* flags */
NULL, /* child setup */
NULL, /* user data */
NULL, /* stdout */
NULL, /* stderr */
&exit_status,
&error))
{
g_debug ("... %s", error->message);
goto out;
}
if (exit_status != 0)
{
g_debug ("... wait status %d", exit_status);
goto out;
}
g_debug ("... it works");
ret = TRUE;
out:
g_free (helper);
g_clear_error (&error);
return ret;
}
gboolean
srt_architecture_can_run_i386 (void)
{
/* TODO */
#if defined(__i386__)
return TRUE;
#else
return FALSE;
#endif
return _srt_architecture_can_run ("i386-linux-gnu");
}
gboolean
srt_architecture_can_run_x86_64 (void)
{
/* TODO */
#if defined(__x86_64__) && defined(__LP64__)
return TRUE;
#else
return FALSE;
#endif
return _srt_architecture_can_run ("x86_64-linux-gnu");
}
......@@ -21,6 +21,8 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
libdl = c_compiler.find_library('dl', required : false)
libsteamrt_sources = [
'architecture.c',
]
......@@ -41,9 +43,13 @@ libsteamrt = library(
c_args : [
'-DG_LOG_DOMAIN="' + meson.project_name() + '"',
'-D_SRT_COMPILATION',
'-D_GNU_SOURCE',
'-D_SRT_SONAME="libsteam-runtime-tools-' + api_major + '.so.' + abi_major + '"',
'-D_SRT_MULTIARCH="' + multiarch + '"',
'-D_SRT_API_MAJOR="' + api_major + '"',
],
include_directories : project_include_dirs,
dependencies : [glib, gobject],
dependencies : [glib, gobject, libdl],
soversion : abi_major,
version : abi_major + '.' + abi_minor,
install : true,
......
......@@ -24,6 +24,7 @@
test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'helpers'))
tests = [
'architecture',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment