Skip to content

Commit

Permalink
Generalized custom path configuration/build support.
Browse files Browse the repository at this point in the history
  • Loading branch information
toots committed Jun 9, 2012
1 parent c1663d6 commit 824a11c
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 30 deletions.
12 changes: 6 additions & 6 deletions Makefile
Expand Up @@ -25,7 +25,7 @@ doc-local: all
.PHONY: system-install gentoo-install finish-configure

finish-configure:
ifneq ($(OS_TYPE),Win32)
ifneq ($(CUSTOM_PATH),yes)
@echo let tts_program = \"$(libdir)/liquidsoap/$(libs_dir_version)/liquidtts\" >> src/configure.ml
@echo let rundir = \"$(localstatedir)/run/liquidsoap\" >> src/configure.ml
@echo let logdir = \"$(localstatedir)/log/liquidsoap\" >> src/configure.ml
Expand All @@ -34,11 +34,11 @@ ifneq ($(OS_TYPE),Win32)
@echo let \(\) = add_subst \"\<sysrundir\>\" \"$(localstatedir)/run/liquidsoap\" >> src/configure.ml
@echo let \(\) = add_subst \"\<syslogdir\>\" \"$(localstatedir)/log/liquidsoap\" >> src/configure.ml
else
@echo let tts_program = \"liquidtts\" >> src/configure.ml
@echo let rundir = \"run\" >> src/configure.ml
@echo let logdir = \"logs\" >> src/configure.ml
@echo let plugins_dir = \"plugins\" >> src/configure.ml
@echo let libs_dir = \"libs\" >> src/configure.ml
@echo let tts_program = get_dir \"liquidtts\" >> src/configure.ml
@echo let rundir = get_dir \"run\" >> src/configure.ml
@echo let logdir = get_dir \"logs\" >> src/configure.ml
@echo let plugins_dir = get_dir \"plugins\" >> src/configure.ml
@echo let libs_dir = get_dir \"libs\" >> src/configure.ml
@echo let \(\) = add_subst \"\<sysrundir\>\" \".\" >> src/configure.ml
@echo let \(\) = add_subst \"\<syslogdir\>\" \".\" >> src/configure.ml
endif
Expand Down
1 change: 1 addition & 0 deletions Makefile.defs.in
Expand Up @@ -27,6 +27,7 @@ CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@
OS_TYPE = @OS_TYPE@
CUSTOM_PATH = @W_CUSTOM_PATH@
EXEEXT = @EXEEXT@
CAMLP4O = @CAMLP4O@

Expand Down
54 changes: 47 additions & 7 deletions configure.ac
Expand Up @@ -259,6 +259,30 @@ AC_SUBST(TCP_NODELAY_VALUE)

AC_SUBST(BYTE)

AC_ARG_ENABLE([custom-path],
AS_HELP_STRING([--enable-custom-path],[Enable custom path support for loading liquidsoap's dependencies (always enable for win32 builds).]))

if test "$OS_TYPE" = "Win32" -o "x$enable_custom_path" = "xyes"; then
W_CUSTOM_PATH="yes"
w_CUSTOM_PATH="ok"
cat >> src/configure.ml <<__BLAH__
let get_dir d =
let dir =
Utils.resolve_path (Filename.dirname Sys.executable_name)
in
let cwd =
match Utils.getenv_opt "LIQUIDSOAP_BASE_DIR" with
| None -> dir
| Some path -> Utils.resolve_path ~cwd:dir path
in
Utils.resolve_path ~cwd d
__BLAH__
else
W_CUSTOM_PATH="no"
w_CUSTOM_PATH=""
fi
AC_SUBST(W_CUSTOM_PATH)

#
# Libs
#
Expand Down Expand Up @@ -536,11 +560,25 @@ let file_mime = None
let data_mime = None
EOCONF
else
if text =z "$w_CUSTOM_PATH"; then
cat >> src/configure.ml <<EOCONF
let magic_cookie = Magic.create ~flags:[[Magic.Mime; Magic.Symlink]] [[]]
let file_mime = Some (Magic.file magic_cookie)
let data_mime = Some (Magic.buffer magic_cookie)
EOCONF
else
cat >> src/configure.ml <<EOCONF
let magic_file =
let cwd = Filename.dirname Sys.executable_name in
let magic =
Utils.getenv ~default:(get_dir "magic/magic.mgc") "MAGIC"
in
Utils.resolve_path ~cwd magic
let magic_cookie = Magic.create ~flags:[[Magic.Mime; Magic.Symlink]] [[magic_file]]
let file_mime = Some (Magic.file magic_cookie)
let data_mime = Some (Magic.buffer magic_cookie)
EOCONF
fi
fi

#
Expand All @@ -565,23 +603,24 @@ else
# Use Camomile with environment variables if
# available
if test -f $camdir/camomileLibraryDyn.cmi ; then
if test "$OS_TYPE" \!= "Win32" ; then
if test -z "$w_CUSTOM_PATH"; then
camencoding=CamomileLibraryDyn.$camencoding
else
# For win32, we use the functorial version
# with our own config.
camencoding="CamomileLibrary.CharEncoding.Configure(CamomileConfig)"
cat >> src/configure.ml <<EOCONF
module CamomileConfig =
struct
let datadir = Filename.concat "camomile" "database"
let localedir = Filename.concat "camomile" "locales"
let charmapdir = Filename.concat "camomile" "charmaps"
let unimapdir = Filename.concat "camomile" "mappings"
let datadir = Filename.concat (get_dir "camomile") "database"
let localedir = Filename.concat (get_dir "camomile") "locales"
let charmapdir = Filename.concat (get_dir "camomile") "charmaps"
let unimapdir = Filename.concat (get_dir "camomile") "mappings"
end
EOCONF
fi
else
if test -n "$w_CUSTOM_PATH"; then
AC_MSG_ERROR([Your camomile module is too old to support loading from a custom path.. Please upgrade it or disable custom path loading.])
fi
if test -f $camdir/camomileLibrary.cmi ; then
camencoding=CamomileLibrary.Default.$camencoding
fi
Expand Down Expand Up @@ -834,6 +873,7 @@ cat <<EOMSG
Version : $OCAML_MAJOR.$OCAML_MINOR.$OCAML_REVISION
OS : $OS_TYPE
Plugins :$PLUGINS
Custom path : $W_CUSTOM_PATH
OCAML_CFLAGS : $liquidsoap_ocamlcflags
OCAML_LFLAGS : $liquidsoap_ocamllflags
CFLAGS : $CFLAGS
Expand Down
80 changes: 80 additions & 0 deletions doc/content/custom-path.txt
@@ -0,0 +1,80 @@
title: Custom loading path

h3. Basics

Starting with version @1.0.1@, it is possible to build a liquidsoap binary that can load
all its dependencies from any arbitrary path. This is very useful to distribute a liquidsoap
bundled binary, independent of the distribution used.

A custom loading path is a directory that contains the following file/directories:
* @./camomile@: Camomile shared data. They are usually located in @/usr/(local/)share/camomile@
* @./libs@: pervasive scripts. Their are located in @liquidsoap/scripts@ in liquidsoap's sources
* @./log@: default log directories
* @./magic@: directory for magic files. See below for more details.
* @./plugins@: default plugins directory (most likely empty)
* @./run@: default runtime files directory
* @liquidtts@: @liquidtts@ script.

h3. Adding liquidsoap binary

In order to ship a liquidsoap binary which is independent of the distribution it will
be run on, one need to also include its dynamic libraries, except for the most common.
The following command may be used to list them:

%%
ldd ./liquidsoap | grep usr | cut -d' ' -f 3
%%

Those libraries are usually copied into a @./ld@ directory. Then, the @LD_LIBRARY_PATH@
is used to point the dynamic loader to this directory.

Finally, the @liquidsoap@ library is usually added in @./bin/liquidsoap@

h3. Configuration variables

In the following, configuration variables may refer to either absolute or relative paths. If referring to
a relative path, the path is resolved relatively to the directory where the @liquidsoap@ binary
is located at.

In order to tell liquidsoap where its custom path is located, you need to set the
@LIQUIDSOAP_BASE_DIR@.

Another important variable is @MAGIC@. It tells liquidsoap where to load the libmagic's
definitions and defaults to @../magic/magic.mgc@. Older versions of libmagic may
require to use @magic/magic.mime@ instead.

h3. Full example

For a fully-functional example, you can check our "heroku buildpack":https://github.com/savonet/heroku-buildpack-liquidsoap.
Its layout is:

%%
./bin
./bin/liquidsoap
./camomile
./camomile/charmaps
(...)
./ld
./ld/libao.so.2
(...)
./libs
./libs/externals.liq
(...)
./liquidtts
./log
./magic
./magic/magic.mime
./plugins
./run
%%

Its configuration variables are set to:

%%
LD_LIBRARY_PATH=/path/to/ld
LIQUIDSOAP_BASE_DIR=..
MAGIC=../magic/magic.mime
%%

As you can see, we use an old version of @libmagic@ so we need to load @magic.mime@ instead of @magic.mgc@.

3 changes: 3 additions & 0 deletions doc/content/documentation.txt
Expand Up @@ -13,6 +13,9 @@ just browse the "reference":reference.html and compose your dream stream.
If you downloaded a source tarball of liquidsoap, you may first read the
"build instructions":build.html.

If you are looking for a way to build a distribution-independant bundle of
liquidsoap, you may want to read the "custom path":custom-path.html page.

h4@general. General tutorials

* "Quickstart":quick_start.html: where anyone should start.
Expand Down
2 changes: 1 addition & 1 deletion src/lang/lang_builtins.ml
Expand Up @@ -1324,7 +1324,7 @@ let () =
is not set."
["",Lang.string_t,None,None] Lang.string_t
(fun p ->
Lang.string (Unix.getenv (Lang.to_string (List.assoc "" p))))
Lang.string (Utils.getenv ~default:"" (Lang.to_string (List.assoc "" p))))

let () =
add_builtin "setenv" ~cat:Sys
Expand Down
7 changes: 1 addition & 6 deletions src/lang/lang_types.ml
Expand Up @@ -20,12 +20,7 @@
*****************************************************************************)

let debug =
try
ignore (Sys.getenv "LIQUIDSOAP_DEBUG_LANG") ;
true
with
| Not_found -> false
let debug = Utils.getenv_opt "LIQUIDSOAP_DEBUG_LANG" <> None

(* Type information comes attached to the AST from the parsing,
* with appropriate sharing of the type variables. Then the type inference
Expand Down
36 changes: 31 additions & 5 deletions src/tools/utils.ml
Expand Up @@ -28,6 +28,34 @@ external force_locale : unit -> unit = "liquidsoap_set_locale"
let () =
force_locale ()

(* Resolve a path. *)
let resolve_path ?cwd path =
let cwd =
match cwd with
| None -> Sys.getcwd()
| Some cwd -> cwd
in
if Filename.is_relative path then
begin
Filename.concat cwd path
end
else
path

(* Getenv with default value. *)
let getenv ~default value =
try
Sys.getenv value
with
| Not_found -> default

(* Getenv with option result. *)
let getenv_opt value =
try
Some (Sys.getenv value)
with
| Not_found -> None

(* Several list utilities *)

let rec make_list n v = if n = 0 then [] else v::(make_list (n-1) v)
Expand Down Expand Up @@ -483,9 +511,7 @@ let rec mkdir ~perm dir =

(** Expand ~ notation in filenames. *)
let home_unrelate =
let home =
try Some (Sys.getenv "HOME") with Not_found -> None
in
let home = getenv_opt "HOME" in
let unrel s =
let len = String.length s in
if len < 2 then
Expand All @@ -511,9 +537,9 @@ let home_unrelate =

let get_tempdir () =
if Sys.os_type = "Win32" then
(try Sys.getenv "TEMP" with Not_found -> "C:\temp")
getenv ~default:"C:\\temp" "TEMP"
else
(try Sys.getenv "TMPDIR" with Not_found -> "/tmp")
getenv ~default:"/tmp" "TMPDIR"

(** Decode Base64-encoded data *)
let decode64 s =
Expand Down
6 changes: 1 addition & 5 deletions src/tools/wav.ml
Expand Up @@ -59,11 +59,7 @@ let () = Utils.register_error_translator error_translator

(* open file and verify it has the right format *)

let debug =
try
ignore (Sys.getenv "LIQUIDSOAP_DEBUG_WAV") ; true
with
| Not_found -> false
let debug = Utils.getenv_opt "LIQUIDSOAP_DEBUG_WAV" <> None

let read_header read_ops ic =
let really_input = read_ops.really_input in
Expand Down

0 comments on commit 824a11c

Please sign in to comment.