Use cbindgen

If we're going to scale out our oxidation, let's follow
the path of Firefox (and other projects) further and use
cbindgen: https://github.com/eqrion/cbindgen

It's actually nice that `cbindgen` is packaged today in Fedora,
but I doubt it is elsewhere; we may end up needing to push
that forward, or just vendor it via a `build.rs` script and Cargo.

I chose to rename things to `ROR`/`ror_` since it's shorter.  I
am tempted a bit to rename our internal functions to just `ro_` to
or so.

Closes: #1516
Approved by: jlebon
This commit is contained in:
Colin Walters 2018-08-24 10:42:31 -04:00 committed by Atomic Bot
parent 279e7c4f1b
commit d2b0e42bfc
8 changed files with 52 additions and 50 deletions

View File

@ -95,8 +95,13 @@ $(librpmostree_rust_path): Makefile $(LIBRPMOSTREE_RUST_SRCS)
$(cargo) build --verbose $${frozen} $(CARGO_RELEASE_ARGS)
EXTRA_DIST += $(LIBRPMOSTREE_RUST_SRCS) rust/Cargo.lock
rpm_ostree_CFLAGS += -Irust/include $(PKGDEP_RPMOSTREE_RS_CFLAGS)
rpm_ostree_SOURCES += rust/include/librpmostree-rust.h
# See rust/build.rs - it uses cbindgen as part of the Rust build
rpmostree-rust.h: $(librpmostree_rust_path)
$(AM_V_GEN) src=$$(find @abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/ -name 'rpmostree-rust.h') && \
test -n "$${src}" && ln -sfr "$${src}" rpmostree-rust.h
BUILT_SOURCES += rpmostree-rust.h
rpm_ostree_CFLAGS += $(PKGDEP_RPMOSTREE_RS_CFLAGS)
rpm_ostree_LDADD += $(librpmostree_rust_path) $(PKGDEP_RPMOSTREE_RS_LIBS)
rustfmt:
rustfmt $(LIBRPMOSTREE_RUST_SRCS)

View File

@ -2,6 +2,7 @@
name = "rpmostree-rust"
version = "0.1.0"
authors = ["Colin Walters <walters@verbum.org>"]
build = "build.rs"
[dependencies]
serde = "1.0"
@ -16,6 +17,9 @@ tempfile = "3.0.3"
openat = "0.1.15"
curl = "0.4.14"
[build-dependencies]
cbindgen = "0.6.3"
[lib]
name = "rpmostree_rust"
path = "src/lib.rs"

24
rust/build.rs Normal file
View File

@ -0,0 +1,24 @@
// See https://bugzilla.redhat.com/show_bug.cgi?id=1608670#c3
// and https://github.com/projectatomic/rpm-ostree/pull/1516
extern crate cbindgen;
fn run() -> Result<(), String> {
let out_dir_v = std::env::var("OUT_DIR").expect("OUT_DIR is unset");
let out_dir = std::path::Path::new(&out_dir_v);
let bindings = cbindgen::generate(std::path::Path::new(".")).map_err(|e| e.to_string())?;
// This uses unwraps internally; it'd be good to submit a patch
// to add a Result-based API.
bindings.write_to_file(out_dir.join("rpmostree-rust.h"));
Ok(())
}
fn main() {
match run() {
Ok(_) => {}
Err(e) => {
eprintln!("error: {}", e);
std::process::exit(1)
}
}
}

6
rust/cbindgen.toml Normal file
View File

@ -0,0 +1,6 @@
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
language = "C"
header = "#include <gio/gio.h>\ntypedef GError RORGError;"
[export]
prefix = "ROR"

View File

@ -1,37 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2018 Jonathan Lebon <jonathan@jlebon.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#pragma once
typedef struct RpmOstreeRsTreefile RpmOstreeRsTreefile;
RpmOstreeRsTreefile *rpmostree_rs_treefile_new (const char *filename,
const char *arch,
int workdir_dfd,
GError **error);
int rpmostree_rs_treefile_to_json (RpmOstreeRsTreefile *tf, GError **error);
const char *rpmostree_rs_treefile_get_rojig_spec_path (RpmOstreeRsTreefile *tf);
void rpmostree_rs_treefile_free (RpmOstreeRsTreefile *tf);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(RpmOstreeRsTreefile, rpmostree_rs_treefile_free);
int rpmostree_rs_download_to_fd (const char *url, GError **error);

View File

@ -69,7 +69,7 @@ fn dir_from_dfd(fd: libc::c_int) -> io::Result<openat::Dir> {
}
#[no_mangle]
pub extern "C" fn rpmostree_rs_treefile_new(
pub extern "C" fn ror_treefile_new(
filename: *const libc::c_char,
arch: *const libc::c_char,
workdir_dfd: libc::c_int,
@ -94,7 +94,7 @@ pub extern "C" fn rpmostree_rs_treefile_new(
}
#[no_mangle]
pub extern "C" fn rpmostree_rs_treefile_to_json(
pub extern "C" fn ror_treefile_to_json(
tf: *mut Treefile,
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
@ -110,7 +110,7 @@ pub extern "C" fn rpmostree_rs_treefile_to_json(
}
#[no_mangle]
pub extern "C" fn rpmostree_rs_treefile_get_rojig_spec_path(
pub extern "C" fn ror_treefile_get_rojig_spec_path(
tf: *mut Treefile,
) -> *const libc::c_char {
assert!(!tf.is_null());
@ -123,7 +123,7 @@ pub extern "C" fn rpmostree_rs_treefile_get_rojig_spec_path(
}
#[no_mangle]
pub extern "C" fn rpmostree_rs_treefile_free(tf: *mut Treefile) {
pub extern "C" fn ror_treefile_free(tf: *mut Treefile) {
if tf.is_null() {
return;
}
@ -133,7 +133,7 @@ pub extern "C" fn rpmostree_rs_treefile_free(tf: *mut Treefile) {
}
#[no_mangle]
pub extern "C" fn rpmostree_rs_download_to_fd(
pub extern "C" fn ror_download_to_fd(
url: *const libc::c_char,
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {

View File

@ -125,7 +125,7 @@ typedef struct {
gboolean rojig_spec_in_workdir;
char *previous_checksum;
RpmOstreeRsTreefile *treefile_rs;
RORTreefile *treefile_rs;
JsonParser *treefile_parser;
JsonNode *treefile_rootval; /* Unowned */
JsonObject *treefile; /* Unowned */
@ -156,7 +156,7 @@ rpm_ostree_tree_compose_context_free (RpmOstreeTreeComposeContext *ctx)
g_free (ctx->ref);
g_free (ctx->rojig_spec);
g_free (ctx->previous_checksum);
g_clear_pointer (&ctx->treefile_rs, (GDestroyNotify) rpmostree_rs_treefile_free);
g_clear_pointer (&ctx->treefile_rs, (GDestroyNotify) ror_treefile_free);
g_clear_object (&ctx->treefile_parser);
g_clear_pointer (&ctx->serialized_treefile, (GDestroyNotify)g_bytes_unref);
g_free (ctx);
@ -702,13 +702,13 @@ parse_treefile_to_json (RpmOstreeTreeComposeContext *self,
g_str_has_suffix (treefile_path, ".yml"))
{
const char *arch = self ? dnf_context_get_base_arch (rpmostree_context_get_dnf (self->corectx)) : NULL;
self->treefile_rs = rpmostree_rs_treefile_new (treefile_path, arch,
self->treefile_rs = ror_treefile_new (treefile_path, arch,
self->workdir_tmp.fd,
error);
if (!self->treefile_rs)
return glnx_prefix_error (error, "Failed to load YAML treefile");
glnx_fd_close int json_fd = rpmostree_rs_treefile_to_json (self->treefile_rs, error);
glnx_fd_close int json_fd = ror_treefile_to_json (self->treefile_rs, error);
if (json_fd < 0)
return FALSE;
g_autoptr(GInputStream) json_s = g_unix_input_stream_new (json_fd, FALSE);
@ -1007,7 +1007,7 @@ rpm_ostree_compose_context_new (const char *treefile_pathstr,
self->rojig_spec = g_build_filename (gs_file_get_path_cached (treefile_dir), rojig_spec, NULL);
else if (self->treefile_rs)
{
self->rojig_spec = g_strdup (rpmostree_rs_treefile_get_rojig_spec_path (self->treefile_rs));
self->rojig_spec = g_strdup (ror_treefile_get_rojig_spec_path (self->treefile_rs));
self->rojig_spec_in_workdir = TRUE;
}

View File

@ -1047,7 +1047,7 @@ rpmostree_sort_pkgs_strv (const char *const* pkgs,
g_str_has_prefix (*pkg, "https://"))
{
g_print ("Downloading '%s'... ", *pkg);
glnx_autofd int fd = rpmostree_rs_download_to_fd (*pkg, error);
glnx_autofd int fd = ror_download_to_fd (*pkg, error);
if (fd < 0)
{
g_print ("failed!\n");