Skip to content

Commit 333f045

Browse files
authored
Install sphinx/read-the-docs onto github pages (#207)
The documentation is viewable on https://wavewave.github.io/fficxx The doc generation is triggered on merge onto the master. * add sphinx * start readthedocs * python env with sphinx+myst-parser * read-the-docs theme. migrated README. * doc CI * python version * trigger the docs action only when merged into master
1 parent e926340 commit 333f045

File tree

11 files changed

+331
-15
lines changed

11 files changed

+331
-15
lines changed

.github/workflows/docs.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: docs_pages_workflow
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
build_docs_job:
10+
runs-on: ubuntu-latest
11+
env:
12+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
- name: Set up Python
17+
uses: actions/[email protected]
18+
with:
19+
python-version: 3.11.0
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install -U sphinx
23+
python -m pip install sphinx-rtd-theme
24+
python -m pip install myst-parser
25+
- name: make the sphinx docs
26+
run: |
27+
make -C docs clean
28+
make -C docs html
29+
- name: Init new repo in dist folder and commit
30+
run: |
31+
cd docs/_build/html/
32+
git init
33+
touch .nojekyll
34+
git add -A
35+
git config --local user.email "[email protected]"
36+
git config --local user.name "GitHub Action"
37+
git commit -m 'deploy'
38+
- name: Force push to destination branch
39+
uses: ad-m/[email protected]
40+
with:
41+
github_token: ${{ secrets.GITHUB_TOKEN }}
42+
branch: gh-pages
43+
force: true
44+
directory: ./docs/_build/html

README.md

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,30 +133,24 @@ instance IB B where
133133
```
134134
This instance generation (*implemenation of C++ class*) is automaticaly done by fficxx, but it's not guaranteed for future subclassing. Any type which implements instances of `IA` and `IB` can be regarded as a subclass of `B`, but it's not automatically done as we have in OOP. The scope of fficxx is to generate such implementations only for existing C++ classes.
135135

136+
References
137+
==========
136138

137-
Real World Usage
138-
================
139+
## C Macro tricks
139140

140-
For the time being, to see how to use generated haskell library, check examples for HROOT : [http://ianwookim.org/HROOT/gallery.html](http://ianwookim.org/HROOT/gallery.html) (if you click examples, then you can see the source code for them. )
141-
142-
143-
144-
145-
C Macro tricks
146-
==============
147141
We use C Macro tricks described in the following:
148142
* http://jhnet.co.uk/articles/cpp_magic
149143
* https://stackoverflow.com/questions/45585903/c-macros-how-to-map-another-macro-to-variadic-arguments
150144
* https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
151145
* https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
152146
* https://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros/3048361#3048361
153147

154-
C++ Template tricks
155-
===================
148+
## C++ Template tricks
149+
156150
* https://en.cppreference.com/w/cpp/language/template_argument_deduction
157151
* http://anderberg.me/2016/08/01/c-variadic-templates/
158152
* https://crascit.com/2015/03/21/practical-uses-for-variadic-templates/
159153

160-
C++ Template Peculiarity
161-
========================
154+
## C++ Template Peculiarity
155+
162156
* https://stackoverflow.com/questions/2354210/can-a-c-class-member-function-template-be-virtual

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = .
9+
BUILDDIR = _build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/conf.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
#
3+
# For the full list of built-in configuration values, see the documentation:
4+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
5+
6+
# -- Project information -----------------------------------------------------
7+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8+
9+
import sphinx_rtd_theme
10+
11+
project = 'fficxx'
12+
copyright = '2022, Ian-Woo Kim'
13+
author = 'Ian-Woo Kim'
14+
release = '0.7.0.0'
15+
16+
# -- General configuration ---------------------------------------------------
17+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
18+
19+
extensions = [
20+
'myst_parser',
21+
'sphinx_rtd_theme'
22+
]
23+
24+
templates_path = ['_templates']
25+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
26+
27+
28+
29+
# -- Options for HTML output -------------------------------------------------
30+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
31+
32+
html_theme = 'sphinx_rtd_theme'
33+
html_static_path = ['_static']

docs/getting_started.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Getting Started
2+
===============
3+
4+
fficxx is mainly packaged in nix.
5+
`shell.nix` is for development,
6+
```
7+
nix-shell shell.nix
8+
```
9+
and `use.nix` is for using the generated binding package.
10+
```
11+
nix-shell use.nix
12+
```
13+
14+
For all build,
15+
```
16+
nix-build release.nix
17+
```

docs/index.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
.. fficxx documentation master file, created by
2+
sphinx-quickstart on Thu Dec 29 11:23:22 2022.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
Welcome to fficxx's documentation!
7+
==================================
8+
9+
fficxx ("eff fix") is an automatic haskell Foreign Function Interface (FFI) generator to C++.
10+
11+
To use fficxx, you write a Haskell model of the C++ public interfaces and fficxx generates both a C wrapper and associated haskell functions and type classes which reflect specified model of the C++ interfaces. It is currently the user's responsibility to specify a correct model of the C++ interfaces, because fficxx does not presently check for model correctness.
12+
13+
While haskell has a well-specified standard for C FFI, making haskell-C++ FFI is an arbitrary and painful process. Since Object-Oriented Programming (OOP) paradigm and Functional Programming (FP) paradigm are different, automatic translation of C++ libraries to haskell libraries is not a straightforward task. The goal of fficxx is to minimize this disparity and maximize user's convenience by providing familiar interface to the original C++ library as a result.
14+
15+
Public Haskell-C++ binding generated by fficxx are now collected in `fficxx-projects <https://github.com/wavewave/fficxx-projects>`_.
16+
17+
fficxx is separated into generator part and runtime part:
18+
19+
* fficxx : FFI types and binding generator library
20+
* fficxx-runtime : runtime modules needed for various common routines
21+
22+
Haskell packages that are generated from fficxx will be dependent on fficxx-runtime.
23+
24+
In addition, C++ standard library under `std` namespace is being generated as a package from fficxx.
25+
* stdcxx: generated by ./stdcxx-gen/Gen.hs
26+
27+
.. toctree::
28+
:maxdepth: 2
29+
:caption: Contents:
30+
31+
getting_started
32+
oop_model_in_fficxx
33+
real_world_usage
34+
references
35+
36+
Indices and tables
37+
==================
38+
39+
* :ref:`genindex`
40+
* :ref:`modindex`
41+
* :ref:`search`

docs/make.bat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@ECHO OFF
2+
3+
pushd %~dp0
4+
5+
REM Command file for Sphinx documentation
6+
7+
if "%SPHINXBUILD%" == "" (
8+
set SPHINXBUILD=sphinx-build
9+
)
10+
set SOURCEDIR=.
11+
set BUILDDIR=_build
12+
13+
%SPHINXBUILD% >NUL 2>NUL
14+
if errorlevel 9009 (
15+
echo.
16+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17+
echo.installed, then set the SPHINXBUILD environment variable to point
18+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
19+
echo.may add the Sphinx directory to PATH.
20+
echo.
21+
echo.If you don't have Sphinx installed, grab it from
22+
echo.https://www.sphinx-doc.org/
23+
exit /b 1
24+
)
25+
26+
if "%1" == "" goto help
27+
28+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29+
goto end
30+
31+
:help
32+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33+
34+
:end
35+
popd

docs/oop_model_in_fficxx.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
OOP Model in fficxx
2+
===================
3+
4+
fficxx generates haskell codes at raw level (C wrapper and haskell foreign pointer that are directly matched with C/C++ types) and at high level (newtype wrapper for raw level pointer and haskell typeclasses reflecting OOP class hierarchy). Haskell does not have a concept of subtyping, i.e. we do not provide any easy way to create a new subclass and overload member functions from existing classes on haskell side. However, fortunately, one can describe the OOP subclass relationship using a typeclass interface as a contract for a class `b` to be equal to or a subclass of `a`. In a sense, typeclasses are Interface Definition Language (IDL) for describing OOP classes. Thus, a C++ class is represented by both haskell concrete type (for a C++ class itself) and typeclass (a set of classes that can be equal to or a subclass of the C++ class).
5+
6+
Assuming that there is a C++ class `A`. fficxx generates a haskell type `A`. This haskell type `A` is nothing but a newtype wrapping `ForeignPtr` tagged by `RawA`.
7+
```
8+
data RawA
9+
10+
newtype A = A (ForeignPtr RawA)
11+
```
12+
`RawA` exists only for the purpose of a phantom type to be used as tags for `Ptr` in FFI imports (`foreign import` statements.) When programming with fficxx-generated code at high level, programmers should seldom encounter `Raw` types. An instance object of C++ class `A` is a value of haskell type `A`. To create an instance, fficxx provides a smart constructor (`newA`) if specified with a corresponding constructor.
13+
14+
Therefore, one can create an instance from a concrete haskell type, and pass it to any functions which needs them. On Haskell side, member functions of a C++ class are nothing but functions whose first argument is the same as the corresponding haskell type to the class. For example, if the class `A` has a member function `foo` of signature `void A::foo( int param )`, then fficxx generates a high level function
15+
```
16+
foo :: A -> CInt -> IO ()
17+
```
18+
which is a wrapper for a raw level FFI call defined by
19+
```
20+
foriegn import ccall "A_foo" c_foo :: Ptr RawA -> CInt -> IO ()
21+
```
22+
where `A_foo` is a generated C shim function for `A::foo`. So one can translate the following C++ code
23+
```
24+
A* a = new A();
25+
a->foo(3);
26+
```
27+
to the haskell code (in do-block of IO monad)
28+
```
29+
do a <- newA
30+
foo a 3
31+
```
32+
Haskell type `A` can be used in the arbitrary argument position. Assume there is another member function `bar` of `A` which takes an object of `A` as an argument like `void A::bar( A* a )`. Then, we have
33+
```
34+
bar :: A -> A -> IO ()
35+
```
36+
for which `x->bar(y)` (`x`,`y` are of class `A`) corresponds to `bar x y`.
37+
38+
In this example, the C++ class `A` may have the following declaration:
39+
```
40+
class A
41+
{
42+
public:
43+
A();
44+
virtual void foo( int );
45+
virtual void bar( A* );
46+
};
47+
```
48+
To reflect subtype relations, fficxx creates an interface typeclass `IA` for `A`, which is defined as
49+
```
50+
class IA a where
51+
foo :: a -> CInt -> IO ()
52+
bar :: (IA b) => a -> b -> IO ()
53+
```
54+
which declares all C++ virtual functions as members. Then, haskell type `A` is a typeclass instance of `IA`:
55+
```
56+
instance IA A where
57+
-- foo :: A -> CInt -> IO ()
58+
foo = ...
59+
-- bar :: (IA b) => A -> b -> IO ()
60+
bar = ...
61+
```
62+
so that `foo` and `bar` functions we considered in the above example were actually defined in the `IA` instance definition of A.
63+
Note that the type signature of `bar` allows generic typeclass instances of `IA` as the argument (paraterized by `b`).
64+
65+
Now consider another C++ class `B` which is a subclass of `A`:
66+
```
67+
class B : public A
68+
{
69+
public:
70+
B();
71+
virtual int baz() ;
72+
}
73+
```
74+
Again, we will have a concrete haskell type `B` and an object of `B` will be created as a value from the `newB` constructor function.
75+
A typeclass `IB` is also generated as well, and it reflects the inheritance relationship for C++ class as constraints:
76+
```
77+
class (IA b) => IB b where
78+
baz :: b -> IO CInt
79+
```
80+
Thanks to the constraints `(IA b) =>` in the declaration, every instance of `IB` must have implementation of `IA`. This is true for `B`, too.
81+
So fficxx generates
82+
```
83+
instance IA B where
84+
foo = ...
85+
bar = ...
86+
87+
instance IB B where
88+
baz = ...
89+
```
90+
This instance generation (*implemenation of C++ class*) is automaticaly done by fficxx, but it's not guaranteed for future subclassing. Any type which implements instances of `IA` and `IB` can be regarded as a subclass of `B`, but it's not automatically done as we have in OOP. The scope of fficxx is to generate such implementations only for existing C++ classes.

docs/real_world_usage.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Real World Usage
2+
================
3+
4+
## Projects
5+
6+
### HROOT
7+
[ROOT](https://root.cern.ch) is a modular scientific software toolkit providing all the functionalities needed to deal with big data processing, statistical analysis, visualisation and storage. It is mainly written in C++ but integrated with other languages.
8+
9+
[HROOT](http://ianwookim.org/HROOT) is a haskell binding to the [ROOT](https://root.cern.ch) library. A haskell script called [HROOT-generate](http://github.com/wavewave/HROOT/blob/master/HROOT-generate) using fficxx generates HROOT packages. Once generated, each package can be directly installable as a cabal package. Currently, C++ interface is defined as a haskell data structure as one can see, for example, in the module [HROOT.Data.Core.Class](https://github.com/wavewave/HROOT/blob/master/HROOT-generate/lib/HROOT/Data/Core/Class.hs).
10+
11+
### hgdal
12+
[GDAL](https://gdal.org) is a translator library for raster and vector geospatial data formats that is released under an X/MIT style Open Source License by the Open Source Geospatial Foundation. As a library, it presents a single raster abstract data model and single vector abstract data model to the calling application for all supported formats. It also comes with a variety of useful command line utilities for data translation and processing.
13+
14+
### hs-ogdf
15+
[OGDF](https://ogdf.uos.de/) stands both for Open Graph Drawing Framework (the original name) and Open Graph algorithms and Data structures Framework.
16+
17+
OGDF is a self-contained C++ library for graph algorithms, in particular for (but not restricted to) automatic graph drawing. It offers sophisticated algorithms and data structures to use within your own applications or scientific projects. The library is available under the GNU General Public License.
18+

docs/references.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
References
2+
==========
3+
4+
## C Macro tricks
5+
6+
We use C Macro tricks described in the following:
7+
* [C Pre-Processor Magic](http://jhnet.co.uk/articles/cpp_magic)
8+
* [C Macros: How to map another macro to variadic arguments?](https://stackoverflow.com/questions/45585903/c-macros-how-to-map-another-macro-to-variadic-arguments)
9+
* [C Preprocessor tricks, tips, and idioms](https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms)
10+
* [Detect empty macro arguments](https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/)
11+
* [Optional Parameters with C++ Macros](https://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros/3048361#3048361)
12+
13+
## C++ Template tricks
14+
15+
* [Template argument deduction](https://en.cppreference.com/w/cpp/language/template_argument_deduction)
16+
* [C++ variadic templates](http://anderberg.me/2016/08/01/c-variadic-templates/)
17+
* [Practical uses for variadic templates](https://crascit.com/2015/03/21/practical-uses-for-variadic-templates/)
18+
19+
## C++ Template Peculiarity
20+
21+
* [Can a class member function template be virtual?](https://stackoverflow.com/questions/2354210/can-a-c-class-member-function-template-be-virtual)

0 commit comments

Comments
 (0)