Skip to content
Snippets Groups Projects
Commit 02ac61d4 authored by Olivier Dion's avatar Olivier Dion Committed by Adrien Béraud
Browse files

agent: Bundle bindings as a shared library

Instead of creating an agent executable, bundle the bindinds into a shared
library.  That way, we're adding an extension that Guile can load at runtime.
This shared library can be installed along with libjami so that users can use
the full power of Scheme to control their Jami accounts.

Also create a `guile-wraper' that compiles against the configuration flags.
This is necessary when building libjami with ASAN because then the executable
either has to LD_PRELOAD ASAN or compile against it.  This minimal wrapper
really just boot guile and start a REPL.

Change-Id: I984d211ff03322b102ebe8650950ac8487711e9d
parent 44f4b003
No related branches found
No related tags found
No related merge requests found
agent
guile-wrapper
pre-inst-env
*.yml
*.txt
......
include $(top_srcdir)/globals.mk
AM_CXXFLAGS += -I$(top_srcdir)/src -I./src $(GUILE_CFLAGS) -rdynamic
AM_CXXFLAGS += -I$(top_srcdir)/src -I./src $(GUILE_CFLAGS)
AM_LDFLAGS += $(GUILE_LIBS)
noinst_PROGRAMS = agent.exe
# This wrapper is necessary because Guile is not compiled with ASAN. If however
# we're using the agent with -fsanitize=address, and just run guile, then
# everything will goes haywire. Thus, just compile a minimal wrapper with the
# same flags passed while configuring so that we can overcome this.
noinst_PROGRAMS = guile-wrapper
agent_exe_SOURCES = \
guile_wrapper_SOURCES = build-aux/guile-wrapper.cpp
lib_LTLIBRARIES = libguile-jami.la
libguile_jami_la_SOURCES = \
src/main.cpp \
src/utils.h \
src/bindings/bindings.cpp \
......@@ -16,12 +24,16 @@ agent_exe_SOURCES = \
src/bindings/signal.cpp \
src/bindings/signal.h
agent_exe_LDADD = $(top_builddir)/src/libring.la
libguile_jami_la_LIBADD = $(top_builddir)/src/libring.la
MODULES = \
agent.scm \
examples/active-agent.scm \
examples/passive-agent.scm \
jami.scm \
jami/account.scm \
jami/call.scm \
jami/conversation.scm \
jami/logger.scm \
jami/signal.scm \
scenarios/bulk-calls/scenario.scm \
......@@ -30,9 +42,10 @@ MODULES = \
GOBJECTS = $(MODULES:%.scm=%.go)
%.go: %.scm
@echo "agent compile $^"
@echo ' GUILD ' $^
@ASAN_OPTIONS=alloc_dealloc_mismatch=0:detect_leaks=0 \
./pre-inst-env agent compile $< $@
./pre-inst-env guile-wrapper --no-auto-compile -e main -s build-aux/compile-scheme.scm $^ $@
compile: $(GOBJECTS)
......
/*
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <libguile.h>
void inner_main(void *, int argc, char **argv)
{
scm_shell(argc, argv);
}
int main(int argc, char *argv[])
{
(void) scm_boot_guile(argc, argv, inner_main, NULL);
__builtin_unreachable();
}
......@@ -36,11 +36,20 @@ abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd -P`"
GUILE_LOAD_COMPILED_PATH="$abs_top_builddir/test/agent${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH"
GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir/test/agent${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH"
GUILE_EXTENSIONS_PATH="$abs_top_builddir:$abs_top_srcdir/test/agent${GUILE_EXTENSIONS_PATH:+:}$GUILE_EXTENSIONS_PATH"
GUILE_AUTO_COMPILE="0"
export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH GUILE_AUTO_COMPILE
export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH GUILE_EXTENSIONS_PATH GUILE_AUTO_COMPILE
LTDL_LIBRARY_PATH="$abs_top_builddir/test/agent${LTDL_LIBRARY_PATH:+:}$LTDL_LIBRARY_PATH"
export LTDL_LIBRARY_PATH
# Define $PATH so that `guile' and friends are easily found.
PATH="$abs_top_srcdir/test/agent:$abs_top_srcdir/contrib/x86_64-unknown-linux-gnu/bin:$PATH"
export PATH
# Not Jami leaks
LSAN_OPTIONS="suppressions=$abs_top_srcdir/test/agent/.lsan-suppress.txt"
export LSAN_OPTIONS
exec "$@"
(define-module (jami)
#:use-module (system foreign-library))
;;; Call DRing::init so that every other bindings work.
;;;
;;; Since Dring::fini is not safe in atexit callback, we also register a exit
;;; hook for finalizing Jami with DRing::fini.
(let* ((libjami (load-foreign-library "libguile-jami"))
(init (foreign-library-function libjami "init"))
(fini (foreign-library-function libjami "fini")))
(init)
(add-hook! exit-hook fini))
(define-module (jami account)
#:use-module (jami)
#:export (accept-trust-request
account->archive
add
add-contact
get-contacts
get-details
remove-contact
send-register
send-truest-request
set-details
subscribe-buddy))
(define-module (jami call)
#:use-module (jami)
#:export (accept
hang-up
hold
place-call/media
refuse
unhold))
(define-module (jami conversation)
#:use-module (jami)
#:export (accept-conversation
get-conversation-members
send-message
get-conversations))
(define-module (jami logger)
#:use-module (jami)
#:use-module ((jami logger bindings) #:prefix ffi:)
#:export (debug
info
warning
error))
#:export-syntax (debug
error
info
warning))
(define-syntax-rule (logging% lvl fmt args ...)
(let* ((source-location (current-source-location))
......
......@@ -15,7 +15,7 @@ export XDG_CACHE_HOME="$tmp_bob"
export XDG_DATA_HOME="$tmp_bob"
export JAMI_LOG_FILE="bob.log"
agent -e main -s $agent_dir/scenarios/bulk-calls/scenario.scm "bob" > bob-guile.txt 2>&1 &
guile-wrapper -e main -s $agent_dir/scenarios/bulk-calls/scenario.scm "bob" > bob-guile.txt 2>&1 &
bob_pid=$!
......@@ -25,7 +25,7 @@ export XDG_CONFIG_HOME="$tmp_alice"
export XDG_CACHE_HOME="$tmp_alice"
export XDG_DATA_HOME="$tmp_alice"
export JAMI_LOG_FILE="alice.log"
agent -e main -s $agent_dir/scenarios/bulk-calls/scenario.scm "alice" "$bob_id" > alice-guile.txt 2>&1
guile-wrapper -e main -s $agent_dir/scenarios/bulk-calls/scenario.scm "alice" "$bob_id" > alice-guile.txt 2>&1
wait $bob_pid
......
......@@ -18,81 +18,31 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Agent */
#include "bindings/bindings.h"
#include "utils.h"
/* Jami */
#include "jami.h"
/* Third parties */
#include <libguile.h>
struct args {
int argc;
char** argv;
};
static bool streq(const char* A, const char* B)
{
return 0 == strcmp(A, B);
}
void*
main_in_guile(void* args_raw)
{
struct args* args = static_cast<struct args*>(args_raw);
install_scheme_primitives();
scm_shell(args->argc, args->argv);
/* unreachable */
return nullptr;
extern "C" {
DRING_PUBLIC void init();
DRING_PUBLIC void fini();
}
void*
compile_in_guile(void* args_raw)
void
init()
{
struct args* args = static_cast<struct args*>(args_raw);
char buf[4096];
DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG));
if (args->argc < 4) {
fprintf(stderr, "Usage: agent.exe compile FILE OUT\n");
exit(EXIT_FAILURE);
if (not DRing::start("")) {
scm_misc_error("Dring::start", NULL, 0);
}
install_scheme_primitives();
snprintf(buf, sizeof(buf),
"(use-modules (system base compile)) (compile-file \"%s\" #:output-file \"%s\")",
args->argv[2], args->argv[3]);
scm_c_eval_string(buf);
scm_gc();
return nullptr;
}
int
main(int argc, char* argv[])
void
fini()
{
struct args args = { argc, argv };
if (argc > 1 && streq(argv[1], "compile")) {
scm_with_guile(compile_in_guile, (void*)&args);
} else {
/* NOTE! It's very important to initialize the daemon before entering Guile!!! */
DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG));
if (not DRing::start("")) {
scm_misc_error("Dring::start", NULL, 0);
}
/* Entering guile context - This never returns */
scm_with_guile(main_in_guile, (void*)&args);
}
exit(EXIT_SUCCESS);
DRing::fini();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment