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> <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> <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>
<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> <varlistentry>
<term><option>cleanup</option> (array of strings)</term> <term><option>cleanup</option> (array of strings)</term>
<listitem><para>An array of file patterns that should be removed at the end. <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 <listitem><para>If this is true, then the data
created in the extension directory is omitted from created in the extension directory is omitted from
the result, and instead packaged in a separate 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> </varlistentry>
</variablelist> </variablelist>
<para> <para>

View File

@ -53,6 +53,7 @@ struct BuilderExtension
char *subdirectory_suffix; char *subdirectory_suffix;
char *version; char *version;
char *versions; char *versions;
gboolean remove_after_build;
}; };
typedef struct typedef struct
@ -77,6 +78,7 @@ enum {
PROP_SUBDIRECTORY_SUFFIX, PROP_SUBDIRECTORY_SUFFIX,
PROP_VERSION, PROP_VERSION,
PROP_VERSIONS, PROP_VERSIONS,
PROP_REMOVE_AFTER_BUILD,
LAST_PROP LAST_PROP
}; };
@ -116,6 +118,10 @@ builder_extension_get_property (GObject *object,
g_value_set_boolean (value, self->bundle); g_value_set_boolean (value, self->bundle);
break; break;
case PROP_REMOVE_AFTER_BUILD:
g_value_set_boolean (value, self->remove_after_build);
break;
case PROP_AUTODELETE: case PROP_AUTODELETE:
g_value_set_boolean (value, self->autodelete); g_value_set_boolean (value, self->autodelete);
break; break;
@ -184,6 +190,10 @@ builder_extension_set_property (GObject *object,
self->bundle = g_value_get_boolean (value); self->bundle = g_value_get_boolean (value);
break; break;
case PROP_REMOVE_AFTER_BUILD:
self->remove_after_build = g_value_get_boolean (value);
break;
case PROP_AUTODELETE: case PROP_AUTODELETE:
self->autodelete = g_value_get_boolean (value); self->autodelete = g_value_get_boolean (value);
break; break;
@ -263,6 +273,13 @@ builder_extension_class_init (BuilderExtensionClass *klass)
"", "",
FALSE, FALSE,
G_PARAM_READWRITE)); 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, g_object_class_install_property (object_class,
PROP_AUTODELETE, PROP_AUTODELETE,
g_param_spec_boolean ("autodelete", g_param_spec_boolean ("autodelete",
@ -361,6 +378,11 @@ builder_extension_get_name (BuilderExtension *self)
return self->name; return self->name;
} }
const char *
builder_extension_get_version (BuilderExtension *self)
{
return self->version;
}
gboolean gboolean
builder_extension_is_bundled (BuilderExtension *self) builder_extension_is_bundled (BuilderExtension *self)
@ -396,6 +418,15 @@ add_argb (BuilderExtension *self,
add_arg (self, args, key, "true"); 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 void
builder_extension_add_finish_args (BuilderExtension *self, builder_extension_add_finish_args (BuilderExtension *self,
GPtrArray *args) 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->subdirectory_suffix);
builder_cache_checksum_str (cache, self->version); builder_cache_checksum_str (cache, self->version);
builder_cache_checksum_str (cache, self->versions); 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, void builder_extension_set_name (BuilderExtension *self,
const char *name); const char *name);
const char * builder_extension_get_name (BuilderExtension *self); const char * builder_extension_get_name (BuilderExtension *self);
const char * builder_extension_get_version (BuilderExtension *self);
gboolean builder_extension_is_bundled (BuilderExtension *self); gboolean builder_extension_is_bundled (BuilderExtension *self);
const char * builder_extension_get_directory (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); GPtrArray *args);
void builder_extension_checksum (BuilderExtension *self, void builder_extension_checksum (BuilderExtension *self,
BuilderCache *cache, BuilderCache *cache,

View File

@ -104,6 +104,7 @@ struct BuilderManifest
GList *modules; GList *modules;
GList *expanded_modules; GList *expanded_modules;
GList *add_extensions; GList *add_extensions;
GList *add_build_extensions;
}; };
typedef struct typedef struct
@ -162,6 +163,7 @@ enum {
PROP_DESKTOP_FILE_NAME_SUFFIX, PROP_DESKTOP_FILE_NAME_SUFFIX,
PROP_COLLECTION_ID, PROP_COLLECTION_ID,
PROP_ADD_EXTENSIONS, PROP_ADD_EXTENSIONS,
PROP_ADD_BUILD_EXTENSIONS,
PROP_EXTENSION_TAG, PROP_EXTENSION_TAG,
LAST_PROP LAST_PROP
}; };
@ -190,6 +192,7 @@ builder_manifest_finalize (GObject *object)
g_clear_object (&self->build_options); g_clear_object (&self->build_options);
g_list_free_full (self->modules, g_object_unref); 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_extensions, g_object_unref);
g_list_free_full (self->add_build_extensions, g_object_unref);
g_list_free (self->expanded_modules); g_list_free (self->expanded_modules);
g_strfreev (self->cleanup); g_strfreev (self->cleanup);
g_strfreev (self->cleanup_commands); g_strfreev (self->cleanup_commands);
@ -345,6 +348,10 @@ builder_manifest_get_property (GObject *object,
g_value_set_pointer (value, self->add_extensions); g_value_set_pointer (value, self->add_extensions);
break; break;
case PROP_ADD_BUILD_EXTENSIONS:
g_value_set_pointer (value, self->add_build_extensions);
break;
case PROP_CLEANUP: case PROP_CLEANUP:
g_value_set_boxed (value, self->cleanup); g_value_set_boxed (value, self->cleanup);
break; break;
@ -563,6 +570,12 @@ builder_manifest_set_property (GObject *object,
self->add_extensions = g_value_get_pointer (value); self->add_extensions = g_value_get_pointer (value);
break; 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: case PROP_CLEANUP:
tmp = self->cleanup; tmp = self->cleanup;
self->cleanup = g_strdupv (g_value_get_boxed (value)); self->cleanup = g_strdupv (g_value_get_boxed (value));
@ -845,6 +858,12 @@ builder_manifest_class_init (BuilderManifestClass *klass)
"", "",
"", "",
G_PARAM_READWRITE)); 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, g_object_class_install_property (object_class,
PROP_CLEANUP, PROP_CLEANUP,
g_param_spec_boxed ("cleanup", g_param_spec_boxed ("cleanup",
@ -1060,19 +1079,26 @@ builder_manifest_serialize_property (JsonSerializable *serializable,
return retval; 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); BuilderManifest *self = BUILDER_MANIFEST (serializable);
JsonNode *retval = NULL; 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; JsonObject *object;
GList *l; GList *l;
object = json_object_new (); 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; BuilderExtension *e = l->data;
JsonNode *child = json_gobject_serialize (G_OBJECT (e)); JsonNode *child = json_gobject_serialize (G_OBJECT (e));
@ -1181,7 +1207,8 @@ builder_manifest_deserialize_property (JsonSerializable *serializable,
return FALSE; 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) if (JSON_NODE_TYPE (property_node) == JSON_NODE_NULL)
{ {
@ -1305,6 +1332,12 @@ builder_manifest_get_add_extensions (BuilderManifest *self)
return self->add_extensions; return self->add_extensions;
} }
GList *
builder_manifest_get_add_build_extensions (BuilderManifest *self)
{
return self->add_build_extensions;
}
static const char * static const char *
builder_manifest_get_runtime_version (BuilderManifest *self) 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(GSubprocess) subp = NULL;
g_autoptr(GPtrArray) args = NULL; g_autoptr(GPtrArray) args = NULL;
g_autofree char *commandline = NULL; g_autofree char *commandline = NULL;
GList *l;
int i; int i;
g_print ("Initializing build dir\n"); 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")); 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++) for (i = 0; self->sdk_extensions != NULL && self->sdk_extensions[i] != NULL; i++)
{ {
const char *ext = self->sdk_extensions[i]; const char *ext = self->sdk_extensions[i];
@ -1607,6 +1644,8 @@ builder_manifest_checksum (BuilderManifest *self,
BuilderCache *cache, BuilderCache *cache,
BuilderContext *context) BuilderContext *context)
{ {
GList *l;
builder_cache_checksum_str (cache, BUILDER_MANIFEST_CHECKSUM_VERSION); builder_cache_checksum_str (cache, BUILDER_MANIFEST_CHECKSUM_VERSION);
builder_cache_checksum_str (cache, self->id); builder_cache_checksum_str (cache, self->id);
/* No need to include version here, it doesn't affect the build */ /* 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) if (self->build_options)
builder_options_checksum (self->build_options, cache, context); 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 static void
@ -2723,6 +2768,9 @@ builder_manifest_finish (BuilderManifest *self,
g_ptr_array_add (args, g_strdup (self->finish_args[i])); 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) for (l = self->add_extensions; l != NULL; l = l->next)
builder_extension_add_finish_args (l->data, args); builder_extension_add_finish_args (l->data, args);
@ -3607,6 +3655,23 @@ builder_manifest_install_deps (BuilderManifest *self,
error)) error))
return FALSE; 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; 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); BuilderOptions *builder_manifest_get_build_options (BuilderManifest *self);
GList * builder_manifest_get_modules (BuilderManifest *self); GList * builder_manifest_get_modules (BuilderManifest *self);
GList * builder_manifest_get_add_extensions (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); const char * builder_manifest_get_branch (BuilderManifest *self);
void builder_manifest_set_default_branch (BuilderManifest *self, void builder_manifest_set_default_branch (BuilderManifest *self,
const char *default_branch); const char *default_branch);