Support using app-extensions during the build

This adds add-build-extensions which is similar to add-extensions
except the extension is added at build-init time, so can be
used during the build. It can also optionally be removed after
the build is done.

This depends on the flatpak work in:
  https://github.com/flatpak/flatpak/pull/1598

With this I was able to build the following app which runs 32bit binaries
in a 64bit build:

```
{
    "app-id": "org.example.Multilib",
    "runtime": "org.freedesktop.Platform",
    "sdk": "org.freedesktop.Sdk",
    "runtime-version": "1.6",
    "command": "/usr/bin/true",
    "add-build-extensions": {
        "org.freedesktop.Platform.Compat32": {
            "directory": "lib/32bit",
            "add-ld-path": "lib",
            "version": "1.6"
        }
    },
    "modules": [
        {
            "name": "test 32bit",
            "buildsystem": "simple",
            "build-commands": [
                "ln -s /app/lib/32bit/lib/ld-linux.so.2 /app/lib/ld-linux.so.2",
                "/app/lib/32bit/bin/echo echoing from 32bit world"
            ]
        }
    ]
}
```

Closes: #129
Approved by: alexlarsson
auto
Alexander Larsson 2018-04-20 11:34:49 +02:00 committed by Atomic Bot
parent 0de0b8d615
commit e779d3c485
5 changed files with 118 additions and 6 deletions

View File

@ -192,6 +192,10 @@
<term><option>add-extensions</option> (objects)</term>
<listitem><para>This is a dictionary of extension objects. The key is the name of the extension. See below for details.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>add-build-extensions</option> (objects)</term>
<listitem><para>This is a dictionary of extension objects similar to add-extensions. The main difference is that the extensions are added early and are available for use during the build.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>cleanup</option> (array of strings)</term>
<listitem><para>An array of file patterns that should be removed at the end.
@ -377,7 +381,14 @@
<listitem><para>If this is true, then the data
created in the extension directory is omitted from
the result, and instead packaged in a separate
extension..</para></listitem>
extension.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>remove-after-build</option> (boolean)</term>
<listitem><para>If this is true, the extension is
removed during when finishing. This is only
interesting for extensions in the
add-build-extensions property.</para></listitem>
</varlistentry>
</variablelist>
<para>

View File

@ -53,6 +53,7 @@ struct BuilderExtension
char *subdirectory_suffix;
char *version;
char *versions;
gboolean remove_after_build;
};
typedef struct
@ -77,6 +78,7 @@ enum {
PROP_SUBDIRECTORY_SUFFIX,
PROP_VERSION,
PROP_VERSIONS,
PROP_REMOVE_AFTER_BUILD,
LAST_PROP
};
@ -116,6 +118,10 @@ builder_extension_get_property (GObject *object,
g_value_set_boolean (value, self->bundle);
break;
case PROP_REMOVE_AFTER_BUILD:
g_value_set_boolean (value, self->remove_after_build);
break;
case PROP_AUTODELETE:
g_value_set_boolean (value, self->autodelete);
break;
@ -184,6 +190,10 @@ builder_extension_set_property (GObject *object,
self->bundle = g_value_get_boolean (value);
break;
case PROP_REMOVE_AFTER_BUILD:
self->remove_after_build = g_value_get_boolean (value);
break;
case PROP_AUTODELETE:
self->autodelete = g_value_get_boolean (value);
break;
@ -263,6 +273,13 @@ builder_extension_class_init (BuilderExtensionClass *klass)
"",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_REMOVE_AFTER_BUILD,
g_param_spec_boolean ("remove-after-build",
"",
"",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_AUTODELETE,
g_param_spec_boolean ("autodelete",
@ -361,6 +378,11 @@ builder_extension_get_name (BuilderExtension *self)
return self->name;
}
const char *
builder_extension_get_version (BuilderExtension *self)
{
return self->version;
}
gboolean
builder_extension_is_bundled (BuilderExtension *self)
@ -396,6 +418,15 @@ add_argb (BuilderExtension *self,
add_arg (self, args, key, "true");
}
void
builder_extension_add_remove_args (BuilderExtension *self,
GPtrArray *args)
{
if (self->remove_after_build)
g_ptr_array_add (args,
g_strdup_printf ("--remove-extension=%s", self->name));
}
void
builder_extension_add_finish_args (BuilderExtension *self,
GPtrArray *args)
@ -440,4 +471,5 @@ builder_extension_checksum (BuilderExtension *self,
builder_cache_checksum_str (cache, self->subdirectory_suffix);
builder_cache_checksum_str (cache, self->version);
builder_cache_checksum_str (cache, self->versions);
builder_cache_checksum_compat_boolean (cache, self->remove_after_build);
}

View File

@ -42,11 +42,14 @@ GType builder_extension_get_type (void);
void builder_extension_set_name (BuilderExtension *self,
const char *name);
const char * builder_extension_get_name (BuilderExtension *self);
const char * builder_extension_get_version (BuilderExtension *self);
gboolean builder_extension_is_bundled (BuilderExtension *self);
const char * builder_extension_get_directory (BuilderExtension *self);
void builder_extension_add_finish_args (BuilderExtension *self,
void builder_extension_add_remove_args (BuilderExtension *self,
GPtrArray *args);
void builder_extension_add_finish_args (BuilderExtension *self,
GPtrArray *args);
void builder_extension_checksum (BuilderExtension *self,
BuilderCache *cache,

View File

@ -104,6 +104,7 @@ struct BuilderManifest
GList *modules;
GList *expanded_modules;
GList *add_extensions;
GList *add_build_extensions;
};
typedef struct
@ -162,6 +163,7 @@ enum {
PROP_DESKTOP_FILE_NAME_SUFFIX,
PROP_COLLECTION_ID,
PROP_ADD_EXTENSIONS,
PROP_ADD_BUILD_EXTENSIONS,
PROP_EXTENSION_TAG,
LAST_PROP
};
@ -190,6 +192,7 @@ builder_manifest_finalize (GObject *object)
g_clear_object (&self->build_options);
g_list_free_full (self->modules, g_object_unref);
g_list_free_full (self->add_extensions, g_object_unref);
g_list_free_full (self->add_build_extensions, g_object_unref);
g_list_free (self->expanded_modules);
g_strfreev (self->cleanup);
g_strfreev (self->cleanup_commands);
@ -345,6 +348,10 @@ builder_manifest_get_property (GObject *object,
g_value_set_pointer (value, self->add_extensions);
break;
case PROP_ADD_BUILD_EXTENSIONS:
g_value_set_pointer (value, self->add_build_extensions);
break;
case PROP_CLEANUP:
g_value_set_boxed (value, self->cleanup);
break;
@ -563,6 +570,12 @@ builder_manifest_set_property (GObject *object,
self->add_extensions = g_value_get_pointer (value);
break;
case PROP_ADD_BUILD_EXTENSIONS:
g_list_free_full (self->add_build_extensions, g_object_unref);
/* NOTE: This takes ownership of the list! */
self->add_build_extensions = g_value_get_pointer (value);
break;
case PROP_CLEANUP:
tmp = self->cleanup;
self->cleanup = g_strdupv (g_value_get_boxed (value));
@ -845,6 +858,12 @@ builder_manifest_class_init (BuilderManifestClass *klass)
"",
"",
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ADD_BUILD_EXTENSIONS,
g_param_spec_pointer ("add-build-extensions",
"",
"",
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_CLEANUP,
g_param_spec_boxed ("cleanup",
@ -1060,19 +1079,26 @@ builder_manifest_serialize_property (JsonSerializable *serializable,
return retval;
}
else if (strcmp (property_name, "add-extensions") == 0)
else if (strcmp (property_name, "add-extensions") == 0 ||
strcmp (property_name, "add-build-extensions") == 0)
{
BuilderManifest *self = BUILDER_MANIFEST (serializable);
JsonNode *retval = NULL;
GList *extensions;
if (self->add_extensions)
if (strcmp (property_name, "add-extensions") == 0)
extensions = self->add_extensions;
else
extensions = self->add_build_extensions;
if (extensions)
{
JsonObject *object;
GList *l;
object = json_object_new ();
for (l = self->add_extensions; l != NULL; l = l->next)
for (l = extensions; l != NULL; l = l->next)
{
BuilderExtension *e = l->data;
JsonNode *child = json_gobject_serialize (G_OBJECT (e));
@ -1181,7 +1207,8 @@ builder_manifest_deserialize_property (JsonSerializable *serializable,
return FALSE;
}
else if (strcmp (property_name, "add-extensions") == 0)
else if (strcmp (property_name, "add-extensions") == 0 ||
strcmp (property_name, "add-build-extensions") == 0)
{
if (JSON_NODE_TYPE (property_node) == JSON_NODE_NULL)
{
@ -1305,6 +1332,12 @@ builder_manifest_get_add_extensions (BuilderManifest *self)
return self->add_extensions;
}
GList *
builder_manifest_get_add_build_extensions (BuilderManifest *self)
{
return self->add_build_extensions;
}
static const char *
builder_manifest_get_runtime_version (BuilderManifest *self)
{
@ -1493,6 +1526,7 @@ builder_manifest_init_app_dir (BuilderManifest *self,
g_autoptr(GSubprocess) subp = NULL;
g_autoptr(GPtrArray) args = NULL;
g_autofree char *commandline = NULL;
GList *l;
int i;
g_print ("Initializing build dir\n");
@ -1530,6 +1564,9 @@ builder_manifest_init_app_dir (BuilderManifest *self,
g_ptr_array_add (args, g_strdup ("--writable-sdk"));
}
for (l = self->add_build_extensions; l != NULL; l = l->next)
builder_extension_add_finish_args (l->data, args);
for (i = 0; self->sdk_extensions != NULL && self->sdk_extensions[i] != NULL; i++)
{
const char *ext = self->sdk_extensions[i];
@ -1607,6 +1644,8 @@ builder_manifest_checksum (BuilderManifest *self,
BuilderCache *cache,
BuilderContext *context)
{
GList *l;
builder_cache_checksum_str (cache, BUILDER_MANIFEST_CHECKSUM_VERSION);
builder_cache_checksum_str (cache, self->id);
/* No need to include version here, it doesn't affect the build */
@ -1633,6 +1672,12 @@ builder_manifest_checksum (BuilderManifest *self,
if (self->build_options)
builder_options_checksum (self->build_options, cache, context);
for (l = self->add_build_extensions; l != NULL; l = l->next)
{
BuilderExtension *e = l->data;
builder_extension_checksum (e, cache, context);
}
}
static void
@ -2723,6 +2768,9 @@ builder_manifest_finish (BuilderManifest *self,
g_ptr_array_add (args, g_strdup (self->finish_args[i]));
}
for (l = self->add_build_extensions; l != NULL; l = l->next)
builder_extension_add_remove_args (l->data, args);
for (l = self->add_extensions; l != NULL; l = l->next)
builder_extension_add_finish_args (l->data, args);
@ -3607,6 +3655,23 @@ builder_manifest_install_deps (BuilderManifest *self,
error))
return FALSE;
for (GList *l = self->add_build_extensions; l != NULL; l = l->next)
{
BuilderExtension *extension = l->data;
const char *name = builder_extension_get_name (extension);
const char *version = builder_extension_get_version (extension);
if (name == NULL || version == NULL)
continue;
g_print ("Dependency Extension: %s %s\n", name, version);
if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation,
name, version,
opt_yes,
error))
return FALSE;
}
return TRUE;
}

View File

@ -58,6 +58,7 @@ char * builder_manifest_get_locale_id_platform (BuilderManifest *self);
BuilderOptions *builder_manifest_get_build_options (BuilderManifest *self);
GList * builder_manifest_get_modules (BuilderManifest *self);
GList * builder_manifest_get_add_extensions (BuilderManifest *self);
GList * builder_manifest_get_add_build_extensions (BuilderManifest *self);
const char * builder_manifest_get_branch (BuilderManifest *self);
void builder_manifest_set_default_branch (BuilderManifest *self,
const char *default_branch);