Exemple #1
0
static int
bz_pacman_add_install_scripts(struct bz_env *env,
                              struct cork_buffer *pkgbuild_buf)
{
    struct cork_buffer  install_buf = CORK_BUFFER_INIT();

    /* Copy each kind of script into install_buf, if present. */
    rii_check(bz_pacman_add_install_script
              (env, &install_buf, "pre_install_script", "pre_install"));
    rii_check(bz_pacman_add_install_script
              (env, &install_buf, "post_install_script", "post_install"));
    rii_check(bz_pacman_add_install_script
              (env, &install_buf, "pre_remove_script", "pre_remove"));
    rii_check(bz_pacman_add_install_script
              (env, &install_buf, "post_remove_script", "post_remove"));

    /* If any of them added content to the install script, save that to a file
     * and reference it in the PKGBUILD. */
    if (install_buf.size > 0) {
        struct cork_path  *install;
        const char  *install_base;
        rip_check(install = bz_env_get_path(env, "pacman.install", true));
        rip_check(install_base =
                  bz_env_get_string(env, "pacman.install_base", true));
        rii_check(bz_create_file(cork_path_get(install), &install_buf, 0640));
        cork_buffer_append_printf(pkgbuild_buf, "install=%s\n", install_base);
    }

    cork_buffer_done(&install_buf);
    return 0;
}
Exemple #2
0
static int
write_header_v1(struct save_data *save_data,
                struct ipset_node_cache *cache, ipset_node_id root)
{
    /* Output the magic number for an IP set, and the file format
     * version that we're going to write. */
    rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true));
    rii_check(write_string(save_data->stream, MAGIC_NUMBER));
    rii_check(write_uint16(save_data->stream, 0x0001));

    /* Determine how many reachable nodes there are, to calculate the
     * size of the set. */
    size_t  nonterminal_count = ipset_node_reachable_count(cache, root);
    size_t  set_size =
        MAGIC_NUMBER_LENGTH +    /* magic number */
        sizeof(uint16_t) +        /* version number  */
        sizeof(uint64_t) +        /* length of set */
        sizeof(uint32_t) +        /* number of nonterminals */
        (nonterminal_count *     /* for each nonterminal: */
         (sizeof(uint8_t) +       /*   variable number */
          sizeof(uint32_t) +      /*   low pointer */
          sizeof(uint32_t)        /*   high pointer */
         ));

    /* If the root is a terminal, we need to add 4 bytes to the set
     * size, for storing the terminal value. */
    if (ipset_node_get_type(root) == IPSET_TERMINAL_NODE) {
        set_size += sizeof(uint32_t);
    }

    rii_check(write_uint64(save_data->stream, set_size));
    rii_check(write_uint32(save_data->stream, nonterminal_count));
    return 0;
}
Exemple #3
0
static int
bz_autotools__stage(void *user_data)
{
    struct bz_env  *env = user_data;
    const char  *package_name;
    struct cork_path  *build_dir;
    struct cork_path  *staging_dir;
    bool  verbose;
    struct cork_env  *exec_env;
    struct cork_exec  *exec;

    rii_check(bz_stage_message(env, "autotools"));

    rip_check(package_name = bz_env_get_string(env, "name", true));
    clog_info("(%s) Stage using autotools", package_name);
    rip_check(build_dir = bz_env_get_path(env, "build_dir", true));
    rip_check(staging_dir = bz_env_get_path(env, "staging_dir", true));
    rie_check(verbose = bz_env_get_bool(env, "verbose", true));

    /* Create the staging path */
    rii_check(bz_create_directory(cork_path_get(staging_dir), 0750));

    /* $ make install */
    exec = cork_exec_new("make");
    cork_exec_add_param(exec, "make");
    cork_exec_add_param(exec, "install");
    cork_exec_set_cwd(exec, cork_path_get(build_dir));
    exec_env = cork_env_clone_current();
    cork_env_add(exec_env, "DESTDIR", cork_path_get(staging_dir));
    cork_exec_set_env(exec, exec_env);
    return bz_subprocess_run_exec(verbose, NULL, exec);
}
Exemple #4
0
static int
save_visit_node(struct save_data *save_data,
                ipset_node_id node_id, serialized_id *dest)
{
    /* Check whether we've already serialized this node. */

    struct cork_hash_table_entry  *entry;
    bool  is_new;
    entry = cork_hash_table_get_or_create
        (save_data->serialized_ids, (void *) (uintptr_t) node_id, &is_new);

    if (!is_new) {
        *dest = (intptr_t) entry->value;
        return 0;
    } else {
        if (ipset_node_get_type(node_id) == IPSET_TERMINAL_NODE) {
            /* For terminals, there isn't really anything to do — we
             * just output the terminal node and use its value as the
             * serialized ID. */

            ipset_value  value = ipset_terminal_value(node_id);

            DEBUG("Writing terminal(%d)", value);
            rii_check(save_data->write_terminal(save_data, value));
            entry->value = (void *) (intptr_t) value;
            *dest = value;
            return 0;
        } else {
            /* For nonterminals, we drill down into the node's children
             * first, then output the nonterminal node. */

            struct ipset_node  *node =
                ipset_node_cache_get_nonterminal(save_data->cache, node_id);
            DEBUG("Visiting node %u nonterminal(x%u? %u: %u)",
                  node_id, node->variable, node->high, node->low);

            /* Output the node's nonterminal children before we output
             * the node itself. */
            serialized_id  serialized_low;
            serialized_id  serialized_high;
            rii_check(save_visit_node(save_data, node->low, &serialized_low));
            rii_check(save_visit_node(save_data, node->high, &serialized_high));

            /* Output the nonterminal */
            serialized_id  result = save_data->next_serialized_id--;
            DEBUG("Writing node %u as serialized node %d = (x%u? %d: %d)",
                  node_id, result,
                  node->variable, serialized_low, serialized_high);

            entry->value = (void *) (intptr_t) result;
            *dest = result;
            return save_data->write_nonterminal
                (save_data, result, node->variable,
                 serialized_low, serialized_high);
        }
    }
}
Exemple #5
0
static int
write_nonterminal_v1(struct save_data *save_data,
                     serialized_id serialized_node,
                     ipset_variable variable,
                     serialized_id serialized_low,
                     serialized_id serialized_high)
{
    rii_check(write_uint8(save_data->stream, variable));
    rii_check(write_uint32(save_data->stream, serialized_low));
    rii_check(write_uint32(save_data->stream, serialized_high));
    return 0;
}
Exemple #6
0
int
vrt_producer_eof(struct vrt_producer *p)
{
    struct vrt_value  *v;
    rii_check(vrt_producer_claim_raw(p->queue, p));
    clog_debug("<%s> EOF %d", p->name, p->last_produced_id);
    v = vrt_queue_get(p->queue, p->last_produced_id);
    v->id = p->last_produced_id;
    v->special = VRT_VALUE_EOF;
    rii_check(vrt_producer_publish(p));
    return vrt_producer_flush(p);
}
Exemple #7
0
static int
cork_copy_once_slice__copy(struct cork_slice *dest,
                           const struct cork_slice *src,
                           size_t offset, size_t length)
{
    struct cork_managed_buffer  *mbuf =
        cork_managed_buffer_new_copy(src->buf, src->size);
    rii_check(cork_managed_buffer_slice(dest, mbuf, offset, length));
    rii_check(cork_managed_buffer_slice
              ((struct cork_slice *) src, mbuf, 0, src->size));
    cork_managed_buffer_unref(mbuf);
    return 0;
}
Exemple #8
0
/* Waits for the slot given by the producer's last_claimed_id to become
 * free.  (This happens when every consumer has finished processing the
 * previous value that would've used the same slot in the ring buffer. */
static int
vrt_wait_for_slot(struct vrt_queue *q, struct vrt_producer *p)
{
    bool  first = true;
    vrt_value_id  wrapped_id = p->last_claimed_id - vrt_queue_size(q);
    if (vrt_mod_lt(q->last_consumed_id, wrapped_id)) {
        clog_debug("<%s> Wait for value %d to be consumed",
                   p->name, wrapped_id);
        vrt_value_id  minimum = vrt_queue_find_last_consumed_id(q);
        while (vrt_mod_lt(minimum, wrapped_id)) {
            clog_trace("<%s> Last consumed value is %d (wait)",
                       p->name, minimum);
            p->yield_count++;
            rii_check(vrt_yield_strategy_yield
                      (p->yield, first, q->name, p->name));
            first = false;
            minimum = vrt_queue_find_last_consumed_id(q);
        }
        p->batch_count++;
        q->last_consumed_id = minimum;
        clog_debug("<%s> Last consumed value is %d", p->name, minimum);
    }

    return 0;
}
Exemple #9
0
static int
bz_pacman__package__is_needed(void *user_data, bool *is_needed)
{
    struct bz_env  *env = user_data;
    const char  *package_name;
    bool  force = false;

    rip_check(package_name = bz_env_get_string(env, "name", true));
    rie_check(force = bz_env_get_bool(env, "force", true));

    if (force) {
        *is_needed = true;
        clog_info("(%s) Force creation of binary package",
                  package_name);
        return 0;
    } else {
        struct cork_path  *package_file;
        rip_check(package_file = bz_env_get_path
                  (env, "pacman.package_file", true));
        clog_info("(%s) Check whether binary package %s exists",
                  package_name, cork_path_get(package_file));
        rii_check(bz_file_exists(cork_path_get(package_file), is_needed));
        *is_needed = !*is_needed;
        return 0;
    }
}
Exemple #10
0
int
vrt_producer_flush(struct vrt_producer *p)
{
    struct vrt_value  *v;

    if (p->last_produced_id == p->last_claimed_id) {
        /* We don't have any queue entries that we've claimed but haven't used,
         * so there's nothing to flush. */
        return 0;
    }

    /* Claim a value to fill in a FLUSH control message. */
    rii_check(vrt_producer_claim_raw(p->queue, p));
    clog_trace("<%s> Flush %d", p->name, p->last_produced_id);
    v = vrt_queue_get(p->queue, p->last_produced_id);
    v->special = VRT_VALUE_FLUSH;

    /* If we've claimed more value than we've produced, fill in the
     * remainder with holes. */
    if (vrt_mod_lt(p->last_produced_id, p->last_claimed_id)) {
        vrt_value_id  i;
        clog_trace("<%s> Holes %d-%d",
                   p->name, p->last_produced_id + 1, p->last_claimed_id);
        for (i = p->last_produced_id + 1;
             vrt_mod_le(i, p->last_claimed_id); i++) {
            struct vrt_value  *v = vrt_queue_get(p->queue, i);
            v->id = i;
            v->special = VRT_VALUE_HOLE;
        }
        p->last_produced_id = p->last_claimed_id;
    }

    /* Then publish the whole chunk. */
    return p->publish(p->queue, p, p->last_claimed_id);
}
Exemple #11
0
static int
clog_stream_handler__annotation(struct clog_handler *vself,
                                struct clog_message *msg,
                                const char *key, const char *value)
{
    struct clog_stream_handler  *self =
        cork_container_of(vself, struct clog_stream_handler, parent);

    if (clog_stream_handler_claim(self)) {
        /* Just claimed the lock; clear the buffer */
        rii_check(clog_formatter_start(self->fmt));
    }

    rii_check(clog_formatter_annotation(self->fmt, key, value));
    return CLOG_CONTINUE;
}
Exemple #12
0
static int
vrt_publish_multi_threaded(struct vrt_queue *q, struct vrt_producer *p,
                           vrt_value_id last_published_id)
{
    bool  first = true;
    vrt_value_id  expected_cursor;
    vrt_value_id  current_cursor;

    /* If there are multiple publisherthen we have to wait until all
     * of the values before the chunk that we claimed have been
     * published.  (If we don't, there will be a hole in the sequence of
     * published records.) */
    expected_cursor = last_published_id - p->batch_size;
    current_cursor = vrt_queue_get_cursor(q);
    clog_debug("<%s> Wait for value %d to be published",
               p->name, expected_cursor);

    while (vrt_mod_lt(current_cursor, expected_cursor)) {
        clog_trace("<%s> Last published value is %d (wait)",
                   p->name, current_cursor);
        rii_check(vrt_yield_strategy_yield
                  (p->yield, first, q->name, p->name));
        first = false;
        current_cursor = vrt_queue_get_cursor(q);
    }

    clog_debug("<%s> Last published value is %d", p->name, current_cursor);
    clog_debug("<%s> Signal publication of value %d (multi-threaded)",
               p->name, last_published_id);
    vrt_queue_set_cursor(q, last_published_id);
    return 0;
}
Exemple #13
0
static int
write_header_dot(struct save_data *save_data,
                 struct ipset_node_cache *cache, ipset_node_id root)
{
    /* Output the opening clause of the GraphViz script. */
    rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true));
    return write_string(save_data->stream, GRAPHVIZ_HEADER);
}
Exemple #14
0
static int
bz_git__load(void *user_data, struct bz_env *env)
{
    struct bz_git_repo  *repo = user_data;
    struct cork_path  *repo_base_dir;
    rip_check(repo_base_dir = bz_env_get_path(env, "repo.base_dir", true));
    rii_check(bz_git_clone(repo->url, repo->commit, repo_base_dir));
    return bz_filesystem_repo_load(repo->repo);
}
static int
cork_read_pipe_read(struct cork_read_pipe *p, char *buf, bool *progress)
{
    if (p->fds[0] == -1) {
        return 0;
    }

    do {
        DEBUG("[read] Reading from pipe %d\n", p->fds[0]);
        ssize_t  bytes_read = read(p->fds[0], buf, BUF_SIZE);
        if (bytes_read == -1) {
            if (errno == EAGAIN) {
                /* We've exhausted all of the data currently available. */
                DEBUG("[read]   No more bytes without blocking\n");
                return 0;
            } else if (errno == EINTR) {
                /* Interrupted by a signal; return so that our wait loop can
                 * catch that. */
                DEBUG("[read]   Interrupted by signal\n");
                return 0;
            } else {
                /* An actual error */
                cork_system_error_set();
                DEBUG("[read]   Error: %s\n", cork_error_message());
                return -1;
            }
        } else if (bytes_read == 0) {
            DEBUG("[read]   End of stream\n");
            *progress = true;
            rii_check(cork_stream_consumer_eof(p->consumer));
            rii_check_posix(close(p->fds[0]));
            p->fds[0] = -1;
            return 0;
        } else {
            DEBUG("[read]   Got %zd bytes\n", bytes_read);
            *progress = true;
            rii_check(cork_stream_consumer_data
                      (p->consumer, buf, bytes_read, p->first));
            p->first = false;
        }
    } while (true);
}
Exemple #16
0
int
vrt_producer_claim(struct vrt_producer *p, struct vrt_value **value)
{
    struct vrt_value  *v;
    rii_check(vrt_producer_claim_raw(p->queue, p));
    v = vrt_queue_get(p->queue, p->last_produced_id);
    v->id = p->last_produced_id;
    v->special = VRT_VALUE_NONE;
    *value = v;
    return 0;
}
Exemple #17
0
/* Claims the next ID that this producer can fill in.  The new value's
 * ID will be stored in p->last_produced_id.  You can get the value
 * itself using vrt_queue_get. */
static int
vrt_producer_claim_raw(struct vrt_queue *q, struct vrt_producer *p)
{
    if (p->last_produced_id == p->last_claimed_id) {
        rii_check(p->claim(q, p));
    }
    p->last_produced_id++;
    clog_trace("<%s> Claimed value %d (%d is available)\n",
               p->name, p->last_produced_id, p->last_claimed_id);
    return 0;
}
Exemple #18
0
static int
clog_stream_handler__message(struct clog_handler *vself,
                             struct clog_message *msg)
{
    struct clog_stream_handler  *self =
        cork_container_of(vself, struct clog_stream_handler, parent);

    if (clog_stream_handler_claim(self)) {
        /* Just claimed the lock; clear the buffer */
        rii_check(clog_formatter_start(self->fmt));
    }

    rii_check(clog_formatter_finish(self->fmt, msg, &self->buf));
    cork_buffer_append(&self->buf, "\n", 1);
    rii_check(cork_stream_consumer_data
              (self->consumer, self->buf.buf, self->buf.size,
               self->first_chunk));
    self->first_chunk = false;
    clog_stream_handler_release(self);
    return CLOG_CONTINUE;
}
Exemple #19
0
static int
bz_git__update(void *user_data, struct bz_env *env)
{
    struct bz_git_repo  *repo = user_data;
    struct cork_path  *repo_base_dir;
    struct cork_path  *repo_git_dir;
    rip_check(repo_base_dir = bz_env_get_path(env, "repo.base_dir", true));
    rip_check(repo_git_dir = bz_env_get_path(env, "repo.git_dir", true));
    rii_check(bz_git_update
              (repo->url, repo->commit, repo_git_dir, repo_base_dir));
    return 0;
}
Exemple #20
0
static int
bz_pacman_add_install_script(struct bz_env *env, struct cork_buffer *buf,
                             const char *var_name, const char *func_name)
{
    struct cork_path  *install_script;
    rie_check(install_script = bz_env_get_path(env, var_name, false));
    if (install_script != NULL) {
        cork_buffer_append_printf(buf, "%s () {\n", func_name);
        rii_check(bz_load_file(cork_path_get(install_script), buf));
        cork_buffer_append_string(buf, "\n}\n");
    }
    return 0;
}
Exemple #21
0
int
vrt_consumer_next(struct vrt_consumer *c, struct vrt_value **value)
{
    do {
        unsigned int  producer_count;
        struct vrt_value  *v;
        rii_check(vrt_consumer_next_raw(c->queue, c));
        v = vrt_queue_get(c->queue, c->current_id);

        switch (v->special) {
            case VRT_VALUE_NONE:
                *value = v;
                return 0;

            case VRT_VALUE_EOF:
                producer_count = cork_array_size(&c->queue->producers);
                c->eof_count++;
                clog_debug("<%s> Detected EOF (%u of %u) at value %d",
                           c->name, c->eof_count, producer_count,
                           c->current_id);

                if (c->eof_count == producer_count) {
                    /* We've run out of values that we know can been
                     * processed.  Notify the world how much we've
                     * processed so far. */
                    clog_debug("<%s> Signal consumption of %d",
                               c->name, c->current_id);
                    vrt_consumer_set_cursor(c, c->current_id);
                    return VRT_QUEUE_EOF;
                } else {
                    /* There are other producers still producing values,
                     * so we should repeat the loop to grab the next
                     * value. */
                    break;
                }

            case VRT_VALUE_HOLE:
                /* Repeat the loop to grab the next value. */
                break;

            case VRT_VALUE_FLUSH:
                /* Return the FLUSH control message. */
                return VRT_QUEUE_FLUSH;

            default:
                cork_unreachable();
        }
    } while (true);
}
Exemple #22
0
static int
bz_pacman__uninstall(void *user_data)
{
    struct bz_env  *env = user_data;
    const char  *package_name;

    rii_check(bz_uninstall_message(env, "pacman"));

    rip_check(package_name = bz_env_get_string(env, "name", true));
    clog_info("(%s) Uninstall using pacman", package_name);
    return bz_subprocess_run
        (false, NULL,
         "sudo", "pacman", "-R", "--noconfirm", package_name,
         NULL);
}
Exemple #23
0
static int
bz_pacman__install__is_needed(void *user_data, bool *is_needed)
{
    struct bz_env  *env = user_data;
    struct bz_value  *ctx = bz_env_as_value(env);
    const char  *package_name;
    struct bz_version  *package_version;
    bool  force;

    rii_check(bz_install_dependency_string("pacman", ctx));
    rip_check(package_name = bz_env_get_string(env, "name", true));
    rie_check(force = bz_env_get_bool(env, "force", true));

    if (force) {
        *is_needed = true;
        clog_info("(%s) Force installation of package",
                  package_name);
        return 0;
    } else {
        struct bz_version  *installed;

        clog_info("(%s) Check whether pacman package is installed",
                  package_name);
        rip_check(package_version = bz_env_get_version(env, "version", true));
        ee_check(installed = bz_arch_native_version_installed(package_name));

        if (installed == NULL) {
            clog_info("(%s) Package is not installed", package_name);
            *is_needed = true;
            return 0;
        } else {
            *is_needed = (bz_version_cmp(installed, package_version) < 0);
            clog_info("(%s) Installed version %s is %s than %s",
                      package_name,
                      bz_version_to_string(installed),
                      *is_needed? "older": "newer",
                      bz_version_to_string(package_version));
            bz_version_free(installed);
            return 0;
        }
    }

error:
    bz_version_free(package_version);
    return -1;
}
Exemple #24
0
static int
bz_pacman__install(void *user_data)
{
    struct bz_env  *env = user_data;
    const char  *package_name;
    struct cork_path  *package_file;

    rii_check(bz_install_message(env, "pacman"));

    rip_check(package_name = bz_env_get_string(env, "name", true));
    rip_check(package_file = bz_env_get_path(env, "pacman.package_file", true));
    clog_info("(%s) Install %s using pacman",
              package_name, cork_path_get(package_file));
    return bz_subprocess_run
        (false, NULL,
         "sudo", "pacman", "-U", "--noconfirm", cork_path_get(package_file),
         NULL);
}
Exemple #25
0
static int
save_bdd(struct save_data *save_data,
         struct ipset_node_cache *cache, ipset_node_id root)
{
    /* First, output the file header. */

    DEBUG("Writing file header");
    rii_check(save_data->write_header(save_data, cache, root));

    /* The serialized node IDs are different than the in-memory node
     * IDs.  This means that, for our nonterminal nodes, we need a
     * mapping from internal node ID to serialized node ID. */

    DEBUG("Creating file caches");
    save_data->serialized_ids = cork_pointer_hash_table_new(0, 0);
    save_data->next_serialized_id = -1;

    /* Trace down through the BDD tree, outputting each terminal and
     * nonterminal node as they're encountered. */

    DEBUG("Writing nodes");

    serialized_id  last_serialized_id;
    ei_check(save_visit_node(save_data, root, &last_serialized_id));

    /* Finally, output the file footer and cleanup. */

    DEBUG("Writing file footer");
    ei_check(save_data->write_footer(save_data, cache, root));

    DEBUG("Freeing file caches");
    cork_hash_table_free(save_data->serialized_ids);
    return 0;

  error:
    /* If there's an error, clean up the objects that we've created
     * before returning. */
    cork_hash_table_free(save_data->serialized_ids);
    return -1;
}
int
cork_consume_file(struct cork_stream_consumer *consumer, FILE *fp)
{
    char  buf[BUFFER_SIZE];
    size_t  bytes_read;
    bool  first = true;

    while (true) {
        while ((bytes_read = fread(buf, 1, BUFFER_SIZE, fp)) > 0) {
            rii_check(cork_stream_consumer_data
                      (consumer, buf, bytes_read, first));
            first = false;
        }

        if (feof(fp)) {
            return cork_stream_consumer_eof(consumer);
        } else if (errno != EINTR) {
            cork_system_error_set();
            return -1;
        }
    }
}
int
cork_consume_fd(struct cork_stream_consumer *consumer, int fd)
{
    char  buf[BUFFER_SIZE];
    ssize_t  bytes_read;
    bool  first = true;

    while (true) {
        while ((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) {
            rii_check(cork_stream_consumer_data
                      (consumer, buf, bytes_read, first));
            first = false;
        }

        if (bytes_read == 0) {
            return cork_stream_consumer_eof(consumer);
        } else if (errno != EINTR) {
            cork_system_error_set();
            return -1;
        }
    }
}
Exemple #28
0
static int
bz_autotools__test(void *user_data)
{
    struct bz_env  *env = user_data;
    const char  *package_name;
    struct cork_path  *build_dir;
    bool  verbose;
    struct cork_exec  *exec;

    rii_check(bz_test_message(env, "autotools"));

    /* $ make check */
    rip_check(package_name = bz_env_get_string(env, "name", true));
    clog_info("(%s) Test using autotools", package_name);
    rip_check(build_dir = bz_env_get_path(env, "build_dir", true));
    rie_check(verbose = bz_env_get_bool(env, "verbose", true));
    exec = cork_exec_new("make");
    cork_exec_add_param(exec, "make");
    cork_exec_add_param(exec, "check");
    cork_exec_set_cwd(exec, cork_path_get(build_dir));
    return bz_subprocess_run_exec(verbose, NULL, exec);
}
Exemple #29
0
static int
bz_pacman__uninstall__is_needed(void *user_data, bool *is_needed)
{
    struct bz_env  *env = user_data;
    struct bz_value  *ctx = bz_env_as_value(env);
    const char  *package_name;
    struct bz_version  *installed;
    rii_check(bz_install_dependency_string("pacman", ctx));
    rip_check(package_name = bz_env_get_string(env, "name", true));
    clog_info("(%s) Check whether pacman package is installed",
              package_name);
    rie_check(installed = bz_arch_native_version_installed(package_name));
    if (installed == NULL) {
        clog_info("(%s) Package is not installed", package_name);
        *is_needed = false;
    } else {
        clog_info("(%s) Version %s is installed",
                  package_name, bz_version_to_string(installed));
        *is_needed = true;
        bz_version_free(installed);
    }
    return 0;
}
Exemple #30
0
static int
bz_autotools__build(void *user_data)
{
    struct bz_env  *env = user_data;
    struct bz_value  *ctx = bz_env_as_value(env);
    const char  *package_name;
    struct cork_path  *build_dir;
    struct cork_path  *source_dir;
    struct cork_path  *configure;
    struct bz_value  *configure_args;
    const char  *pkgconfig_path;
    bool  exists;
    bool  verbose;
    struct cork_exec  *exec;
    struct cork_env  *exec_env;
    struct cork_buffer  buf = CORK_BUFFER_INIT();

    rii_check(bz_install_dependency_string("autoconf", ctx));
    rii_check(bz_install_dependency_string("automake", ctx));
    rii_check(bz_build_message(env, "autotools"));

    rip_check(package_name = bz_env_get_string(env, "name", true));
    rip_check(build_dir = bz_env_get_path(env, "build_dir", true));
    rip_check(source_dir = bz_env_get_path(env, "source_dir", true));
    rip_check(configure =
              bz_env_get_path(env, "autotools.configure.configure", true));
    rie_check(pkgconfig_path = bz_env_get_string(env, "pkgconfig.path", false));
    rie_check(verbose = bz_env_get_bool(env, "verbose", true));

    /* Create the build path */
    rii_check(bz_create_directory(cork_path_get(build_dir), 0750));

    clog_info("(%s) Configure using autotools", package_name);

    /* $ autoreconf -i */
    rii_check(bz_file_exists(cork_path_get(configure), &exists));
    if (!exists) {
        exec = cork_exec_new("autoreconf");
        cork_exec_add_param(exec, "autoreconf");
        cork_exec_add_param(exec, "-i");
        cork_exec_set_cwd(exec, cork_path_get(source_dir));
        ei_check(bz_subprocess_run_exec(verbose, NULL, exec));
    }

#define add_dir(buzzy_name, param_name) \
    do { \
        struct cork_path  *value; \
        ep_check(value = bz_env_get_path(env, buzzy_name, true)); \
        cork_buffer_printf(&buf, "--" param_name "=%s", cork_path_get(value)); \
        cork_exec_add_param(exec, buf.buf); \
    } while (0)

    /* $ ./configure ... */
    exec = cork_exec_new(cork_path_get(configure));
    exec_env = cork_env_clone_current();
    cork_exec_set_env(exec, exec_env);
    cork_exec_add_param(exec, cork_path_get(configure));
    add_dir("prefix", "prefix");
    add_dir("exec_prefix", "exec-prefix");
    add_dir("bin_dir", "bindir");
    add_dir("sbin_dir", "sbindir");
    add_dir("lib_dir", "libdir");
    add_dir("libexec_dir", "libexecdir");
    add_dir("share_dir", "datadir");
    add_dir("man_dir", "mandir");

    /* Add custom configure arguments, if given. */
    configure_args = bz_env_get_value(env, "autotools.configure.args");
    if (configure_args != NULL) {
        struct bz_configure_add_arg  state = { exec, env };

        switch (bz_value_kind(configure_args)) {
            case BZ_VALUE_SCALAR:
                ei_check(bz_configure_add_arg(&state, configure_args));
                break;

            case BZ_VALUE_ARRAY:
                ei_check(bz_array_value_map
                         (configure_args, &state, bz_configure_add_arg));
                break;

            case BZ_VALUE_MAP:
                bz_bad_config("autotools.configure.args cannot be a map");
                goto error;

            default:
                cork_unreachable();
        }
    }

    cork_exec_set_cwd(exec, cork_path_get(build_dir));
    if (pkgconfig_path != NULL) {
        cork_env_add(exec_env, "PKG_CONFIG_PATH", pkgconfig_path);
    }
    ei_check(bz_subprocess_run_exec(verbose, NULL, exec));

    /* $ make */
    clog_info("(%s) Build using autotools", package_name);
    exec = cork_exec_new("make");
    cork_exec_add_param(exec, "make");
    cork_exec_set_cwd(exec, cork_path_get(build_dir));
    ei_check(bz_subprocess_run_exec(verbose, NULL, exec));

    cork_buffer_done(&buf);
    return 0;

error:
    cork_buffer_done(&buf);
    return -1;
}