Skip to content

Commit

Permalink
More docs. [ci skip]
Browse files Browse the repository at this point in the history
  • Loading branch information
skaller committed Nov 22, 2017
1 parent 9fb4de7 commit 39d8794
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 5 deletions.
147 changes: 147 additions & 0 deletions doc/tools/basicoperation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
===============
Basic Operation
===============

Felix is designed to be used, in the first instance,
like Python or other scripting language. You can just
run a text file directly like this:

.. code-block:: bash
flx hello.flx
Behind the scenes, the `flx` command will first run the
Felix compiler executable `flxg` generating some C++
files and some other information.

Then, it runs your chosen C++ compiler to compile and link those
files to binary form.

Finally, it runs the binaries.

You do not need make, autoconf, or any kind of build script
or configuration, it just works!

Where is the executable?
========================

Felix puts the executable here:

.. code-block:: text
$HOME/.felix/cache/binary/$HOME/felix/hello.so
where `$HOME` is your home directory. In other words,
Felix uses a cache, which by default is

.. code-block:: text
$HOME/.felix/cache
to store temporary files. Text files go in:

.. code-block:: text
$HOME/.felix/cache/text
and binary files go in:

.. code-block:: text
$HOME/.felix/cache/binary
The file name used in the appropriate cache uses the prefix of the *absolute*
pathname of the source file.

That's a library not an executable!
===================================

You're right! By default, Felix builds libraries, not programs,
and it builds your program as a shared library. On Linux, this
will have the extension `.so`, on OSX it will be `.dylib` and
on Windows it will be `.dll`.

These library objects are loaded at run time by a small
program executable, it will be called either `flx_run`
or `flx_arun`, which can be found in `build/release/host/bin`.
It will have extension `.exe` on Windows and no extension on
unix like systems. This program is passed the absolute pathname
of the library to load, which it does using `dlopen()` on unix
like systems and `LoadLibrary()` on Windows.

How can I avoid rebuilding my program every time?
=================================================

That's easy. Make a cup of coffee. There's nothing
to do. Felix automatically checks dependencies and
if it would compile the same program you have already
compiled it just runs the already compiled one.

How can I make a standalone executable?
=======================================

You can best do this like so:

.. code-block:: bash
flx --static -c -od . hello.flx
First, the `--static` switch says to do static linkage,
instead of dynamic linkage. Second, the `-c` switch says
to compile and link the program but not run it.
Third, the `-od .` switch says to put the output of the
build process into the current directory `.` using the
basename of the source file `hello` as the basename
of the executable.

On Unix systems `hello` will appear in the current directory
and you can run it by

.. code-block:: bash
./hello
On Windows, `hello.exe` will appear instead,
and you can run it by:

.. code-block:: bash
hello
You can copy this program wherever you like and it will work,
it does not need Felix anymore.

Note that for some complex programs which uses plugins,
the program will have to be able to find the plugins,
which are shared libraries or DLLs, and you will need to also
set up an environment where it can do so. The `flx` program,
even though a statically linked executable, can still load
plugins.

























2 changes: 2 additions & 0 deletions doc/tools/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Contents:
:maxdepth: 2

installation
basicoperation
thirdpartylibraries

Indices and tables
==================
Expand Down
28 changes: 23 additions & 5 deletions doc/tools/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Clone Felix
You first need to configure git, please see git docs.
Then for a user without write access to the Felix repository,
make a workspace directory *in which* the Felix repository
directory will be created. Now grab a copy of Felix:
directory will be created and `cd` into it. Now grab a copy of Felix:

.. code-block:: bash
Expand Down Expand Up @@ -113,12 +113,31 @@ Now you should be able to run the GUI tests:
make tutopt-check
Preserve the SDL2 Patches
-------------------------

The changes you made above to the Felix configuration
will be lost next time you upgrade Felix. To fix this
problem do this:

.. code-block:: bash
mkdir -p $HOME/.felix/config
cp build/release/host/config/sdl2*.fpc $HOME/.felix/config
Next time you build Felix, it will first clobber the changed
files in `build/release/config` and then clobber those changed
files with the ones from `$HOME/.felix/config`, thereby
preserving your modification.


Installation
------------

Felix does *not* have to be installed to work.
I recommend you do *not* install it, at least not yet.
Installation is for enterprise users, rather than personal users.

The reason is that upgrades are frequent: Felix is typically
upgraded every day. Rebuilding Felix is easy, but it is a pain
reinstalling it all the time, it is better initially to run it
Expand Down Expand Up @@ -147,15 +166,14 @@ set already.

For full plugin and dynamic library support, you will also need to
set `LD_LIBRARY_PATH`. Normally, `flx` sets this for you, but if you want
to run Felix build executables directly as standalone programs, *and*
to run Felix built executables directly as standalone programs, *and*
you want to link to Felix shared libraries, including plugins,
then the system linker has to find the libraries so you will also need this:

.. code-block:: bash
export LD_LIBRARY_PATH=/usr/local/lib/felix/felix-latest/host/lib/rtl:$LD_LIBRARY_PATH
Felix does not put its shared libraries in the usual place, directly in
a `/usr/lib` or `/usr/local/lib` directory. This is deliberate.
You need to be able to delete a Felix version, or all of Felix easily,
Expand All @@ -167,11 +185,11 @@ Running in Place
----------------

This option is prefered over installing Felix at the moment,
although it is a little tricker to set up, it make it very
although it is a little tricker to set up, it makes it very
much easier to upgrade Felix.

After you have built Felix, you can use it in place, without
installing it. First you need to do this, make sure you
installing it. First you need to do this: make sure you
are still in the Felix directory, be very careful to use the
correct quotation marks as indicated below!!

Expand Down
133 changes: 133 additions & 0 deletions doc/tools/thirdpartylibraries.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
===========================
Using Third Party Libraries
===========================

Felix is specifically designed to be able to use third party
C and C++ libraries, and to be able to do so without any
makefiles, linkage commands, or other scripts.

To make this happen, there is a configuration database
which tells Felix where the relevant header files and
libraries actually reside in your file system.

In fact, Felix itself uses the very same machinery
to use its own native libraries.

Targets
=======

Felix can build for any targets you can configure.
The default, required, target is called `host`,
and it is your normal programming environment.

Felix splits its data into two parts, `shared` and
the target, usually `host`. The data in `shared` is
common to all targets; it consists of all platform
independent data, including Felix source libraries,
and platform independent C++ header files.

In the target `host` you will find object files and
executables compiled for your specific operating system
by the C++ compiler toolchain selected as the default.

Configuration Database
======================

Inside every platform dependent target, there is a
directory called `config`, you can examine it here
from the Felix install directory:

.. code-block:: bash
ls build/release/host/config
You will see a bunch of files ending in extension `.fpc`.
Each of these files specifies how to use a package with
the basename of the file. Lets look at one:

.. code-block:: text
~/felix>cat build/release/host/config/sdl2.fpc
Generated_from: 3674 "/Users/skaller/felix/src/packages/sdl.fdoc"
Name: SDL2
Description: Simple Direct Media Layer 2.0
cflags: -I/usr/local/include/SDL2
includes: '"SDL.h"'
provides_dlib: -L/usr/local/lib -lSDL2
provides_slib: -L/usr/local/lib -lSDL2
requires_dlibs: ---framework=OpenGL
requires_slibs: ---framework=OpenGL
This is the one on my Mac, which runs OSX. The first line tells
how the file got produced, the second is a common name for
the library which is just documentation too, as is the third
line, which gives more information.

But now come the important lines.

* `cflags` tells the C++ compiler how to find the SDL header file
* `includes` tells Felix what the header file name is
* `provides_dlib` tells C++ how to link the dynamic version of the SDL2 library
* `provides_slib` tells C++ how to link the static version of the SDL2 library
* `requires_dlibs` tells C++ about dependencies of SDL2 dynamic library
* `requires_slibs` tells C++ about dependencies of SDL2 dynamic library

Note that values of these attributes are specific to *your* computer,
and also sometimes to the C++ compiler selected.

When you install a third party library, you have to create an entry
similar to that seen above for the library in the configuration
database for each target where you want to use that library.

On Ubuntu, you will normally only need three lines

.. code-block:: text
includes: '"mylib"'
provides_dlib: -lmylib
provides_slib: -lmylib
because C++ will automatically look in `/usr/lib` for libraries,
and in `/usr/include` for header files. Do not include the
leading `lib` of library file names, nor the trailing `.so`!


Felix Source Code
=================

Now you have installed your library, and added entries
in the configuration database, you can use the library like this:

.. block-code:: felix

type mytype = "mylib::mytype"
requires package "mylib"
;


This Felix code lifts the C++ type `mylib::mytype`
into Felix, naming it `mytype` in Felix, and it tells
Felix that the library providing that C++ types is
in package `mylib` .. which of course is just the name
of the file `mylib.fpc` in the configuration database.

This is how Felix maps abstract component name used
in source code into the compilation and linker switches
needed to use the C++ and binary library components.

The source code is therefore platform independent,
and you can run programs which uses third party
libraries without specifying any linker switches
or other platform specific nonsense every again.
You have to specify it once, in the configuration
database.

Felix is smart, it will only link the library if it
is actually required. If you do not use values of the
type `mytype` then the library will not be linked,
if you do, it will be.





0 comments on commit 39d8794

Please sign in to comment.