Skip to content

rmattes/asdf-shared-library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

asdf-shared-library - Compile and Load Shared Libraries with ASDF

Abstract

Installation

The easiest way to install asdf-shared-library is to check out the git repository at https://github.com/rmattes/asdf-shared-library.git into your local quicklisp directory:

$ cd ~/quicklisp/local-projects
$ git clone https://github.com/rmattes/asdf-shared-library.git

If you have strong reasons not to use quicklisp you shure are smart enough to adapt the install to your local setup.

N.B.: asdf-shared-library is unfinished and alpha ware. You have been warned.

Modus Operandi

Using the shared-library Component

(asdf:defsystem :foo
  :author "Nathan Nasenbaer"
  :license "GPLv2 or later"
  :version "0.1"
  :defsystem-depends-on (#:asdf-shared-library)
  :depends-on (#:cffi)
  :serial t
  :components
  ((:file "package")
   (:shared-library "libfoo"
                    :components ((:c-source "foo.c")
                                 (:c-header "foo.h")
                                 (:c-source "bar.c"))
                    :packages ("jack" "alsa"))
   (:file "foo")))

Where foo.c and bar.c contain:

#include <stdio.h>

void say_hello (void){
  printf ("Hello World!\n");
}

/* ..... */
int strange_number(int in) {
  if (0 > in) {
    return 42;
  }
  return in;
}

And foo.lisp looks like this:

(in-package #:foo)

;;; From foo.c
(cffi:defcfun ("strange_number" strange-number) :int
  (in :int))

;;; From bar.c
(cffi:defcfun ("say_hello" say-hello) :void)

Then the following should work:

(asdf:make :foo)
(foo:say-hello)
(foo:strange-number 21)
(foo:strange-number -21)

Anatomy of the shared-library component

The name of the component denotes the default library name of the generated shared library, so a component “libfoo” will compile to libfoo.so on Linux ond libfoo.dylib on Mac OSX. The following keyword arguments can be provided

:sources
A list of c-source components that will be compiled into the shared library.
:cflags
A list of strings that will be added to the compiler invcation before flags provided from the pkg-config invocation (see below). Please note that the neccessary flags to output a shared library will already be present.
:ldflags
A list of strings that will be added to the compiler invcation before flags provided from the pkg-config invocation (see below)
:packages
A list of “packages”, i.e. a list of what pkg-config call “libraries” that need to be added to the shared library. For each package, asdf-shared-library will call pkg-config to fetch the needed compiler flags and linker flags.

The shared-library component is implemented as a subclass of an ASDF module and can (and actually: should) contain other components. Two types of components are supported, c-sources and c-headers. All ~c-sources of the shared-library module will be used to compile the shared library (the are fed in serial order to the C compiler).

You might ask why we even need to track the c-headers at all. First, we need them for depenency tracking, i.e. any change in a header file should trigger the recompilation of the library. Second, some parts of ASF (or other, external tools) like a bundle operation or a packing/archiving tool neet to know about these files.

Tweaking the compilation process

In some rare cases or on an unusal platform/host it might be neccessary to tweak/customize the compilation process. This is best done by binding some special variables arround loading your system.

The following special varialbles are currently supported:

asdf-shared-library:*compiler*
the compiler used to compile the library
asdf-shared-library:*cflags*
the default compiler flags to generate a shared library. N.B: this string (not a list of strings!) will replace the system efaults, so you better make shure that your flags will produce a valid shared library. Sometimes (string-append asdf-shared-library:*cflags* "-my-extra-flag ") will o the right thing.
asdf-shared-library:*pkg-config-binary*
Which pkg-config binary to call. N.B.: you can modify where pkg-config searches for libraries by setting the PKG_CONFIG_PATH environment variable (see man pkg-config)

Example

Compile your library using LLVM’s c++ compiler

(let ((asdf-shared-library:*compiler* "clang++"))
  (asdf:make *:libfoo))

Know Issues/Todo List

  • Dependency tracking doesn’t honor the components yet.
  • I would be conveninet to (re)use the already existing c-source-file component from ASDF, but, alas, that cmponent assumes that every source file is compiled independent.

Definitly more that will show up.

About

Create/compile and load share dlibraries using ASDF

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •