Skip to content

Commit

Permalink
build: allow to build self-contained executable
Browse files Browse the repository at this point in the history
  • Loading branch information
eworm-de authored and martanne committed May 31, 2017
1 parent 6a7802c commit 7d88cb3
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/vis
/vis-menu
/vis-single
/vis-single-payload.inc
/vis-digraph
*.css
*.gcda
Expand Down
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
# ./configure CC='cc --static'
# make
# docker cp vis:/tmp/vis/vis .
# make vis-single
# docker cp vis:/tmp/vis/vis-single .
FROM alpine:edge
ENV DIR /tmp/vis
WORKDIR $DIR
RUN apk update && apk add musl-dev fortify-headers gcc make libtermkey-dev ncurses-dev ncurses-static lua5.3-dev lua5.3-lpeg lua-lpeg-dev acl-dev
RUN apk update && apk add musl-dev fortify-headers gcc make libtermkey-dev ncurses-dev ncurses-static lua5.3-dev lua5.3-lpeg lua-lpeg-dev acl-dev libarchive-dev xz-dev xz bzip2-dev
RUN sed -i 's/Libs: /Libs: -L${INSTALL_CMOD} /' /usr/lib/pkgconfig/lua5.3.pc
RUN mv /usr/lib/lua/5.3/lpeg.a /usr/lib/lua/5.3/liblpeg.a
RUN sed -i 's/-ltermkey/-ltermkey -lunibilium/' /usr/lib/pkgconfig/termkey.pc
Expand Down
16 changes: 15 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ vis-menu: vis-menu.c
vis-digraph: vis-digraph.c
${CC} ${CFLAGS} ${CFLAGS_AUTO} ${CFLAGS_STD} ${CFLAGS_EXTRA} $< ${LDFLAGS} ${LDFLAGS_STD} ${LDFLAGS_AUTO} -o $@

vis-single-payload.inc: $(EXECUTABLES) lua/*
echo '#ifndef VIS_SINGLE_PAYLOAD_H' > vis-single-payload.inc
echo '#define VIS_SINGLE_PAYLOAD_H' >> vis-single-payload.inc
echo 'unsigned char vis_single_payload[] = {' >> vis-single-payload.inc
tar c $(EXECUTABLES) $$(find lua -name '*.lua') | xz | od -t x1 -A none -v | \
sed 's/\([0-9a-f]\+\)/0x\1,/g;$$s/,$$/ };/' >> vis-single-payload.inc
echo '#endif' >> vis-single-payload.inc

vis-single: vis-single.c vis-single-payload.inc
for e in $(ELF); do \
${STRIP} "$$e"; \
done
${CC} ${CFLAGS} ${CFLAGS_AUTO} ${CFLAGS_STD} ${CFLAGS_EXTRA} $< ${LDFLAGS} ${LDFLAGS_STD} ${LDFLAGS_AUTO} -larchive -lacl -lbz2 -llzma -o $@

debug: clean
@$(MAKE) CFLAGS_EXTRA='${CFLAGS_EXTRA} ${CFLAGS_DEBUG}'

Expand All @@ -91,7 +105,7 @@ test:

clean:
@echo cleaning
@rm -f $(ELF) vis-single vis-*.tar.gz *.gcov *.gcda *.gcno
@rm -f $(ELF) vis-single vis-single-payload.inc vis-*.tar.gz *.gcov *.gcda *.gcno

dist: clean
@echo creating dist tarball
Expand Down
151 changes: 151 additions & 0 deletions vis-single.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#define _GNU_SOURCE

#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#include <archive.h>
#include <archive_entry.h>
#include <sys/acl.h>

#include "vis-single-payload.inc"

int copy_data(struct archive *ar, struct archive *aw) {
int r;
const void *buff;
size_t size;
int64_t offset;

for (;;) {
if ((r = archive_read_data_block(ar, &buff, &size, &offset)) == ARCHIVE_EOF)
return ARCHIVE_OK;

if (r != ARCHIVE_OK) {
fprintf(stderr, "archive_read_data_block() failed: %s\n", archive_error_string(ar));
return r;
}

if ((r = archive_write_data_block(aw, buff, size, offset)) != ARCHIVE_OK) {
fprintf(stderr, "archive_write_data_block() failed: %s\n", archive_error_string(aw));
return r;
}
}

return ARCHIVE_OK;
}

int extract(const char *path) {
struct archive *a;
struct archive_entry *entry;
struct archive *ext;
char * abs_path = NULL;
const char * term;
char * termenv;
int r = ARCHIVE_FAILED;

if ((a = archive_read_new()) == NULL)
return ARCHIVE_FAILED;

if ((r = archive_read_support_filter_xz(a)) != ARCHIVE_OK)
goto out10;

if ((r = archive_read_support_format_tar(a)) != ARCHIVE_OK)
goto out10;

if ((ext = archive_write_disk_new()) == NULL) {
r = ARCHIVE_FAILED;
goto out10;
}

if ((r = archive_read_open_memory(a, vis_single_payload, sizeof(vis_single_payload))) != ARCHIVE_OK) {
fprintf(stderr, "archive_read_open_memory() failed: %s\n", archive_error_string(a));
goto out20;
}

while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
if (asprintf(&abs_path, "%s/%s", path, archive_entry_pathname(entry)) == -1)
goto out20;

archive_entry_set_pathname(entry, abs_path);
free(abs_path);

if ((r = archive_write_header(ext, entry)) != ARCHIVE_OK) {
fprintf(stderr, "archive_write_header() failed: %s\n", archive_error_string(ext));
goto out20;
}

if ((r = copy_data(a, ext)) != ARCHIVE_OK)
goto out20;

if ((r = archive_write_finish_entry(ext)) != ARCHIVE_OK) {
fprintf(stderr, "archive_write_finish_entry() failed: %s\n", archive_error_string(ext));
goto out20;
}
}

out20:
archive_write_close(ext);
archive_write_free(ext);

out10:
archive_read_close(a);
archive_read_free(a);

return ARCHIVE_OK;
}

int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
return remove(fpath);
}

int main(int argc, char **argv) {
char tmp_dirname_template[] = "/tmp/.vis-single-XXXXXX";
const char *tmp_dirname;
char *abs_path = NULL;
const char *term;
char *termenv = NULL;
int child_pid, statval, rc = EXIT_FAILURE;

if ((tmp_dirname = mkdtemp(tmp_dirname_template)) == NULL) {
perror ("mkdtemp: Could not create tmp directory");
goto out10;
}

if (extract(tmp_dirname) != ARCHIVE_OK)
goto out20;

if (asprintf(&abs_path, "%s/vis", tmp_dirname) == -1)
goto out20;

child_pid = fork();
if (child_pid == -1) {
fprintf(stderr, "could not fork!\n");
goto out30;
} else if (child_pid == 0) {
if ((term = getenv("TERM")) == NULL) {
puts("TERM is not defined!");
goto out30;
}

if (asprintf(&termenv, "TERM=%s", term) == -1)
goto out30;

char *env[] = { termenv, NULL };
execve(abs_path, argv, env);
}

waitpid(child_pid, &statval, WUNTRACED|WCONTINUED);
rc = WEXITSTATUS(statval);

out30:
free(abs_path);
free(termenv);

out20:
nftw(tmp_dirname, unlink_cb, 64, FTW_DEPTH|FTW_PHYS);

out10:
return rc;
}

0 comments on commit 7d88cb3

Please sign in to comment.