how to generate documentations with haddock? - haskell

The project I am using does not have docs on Stackage (they're out of date). Here is the original one which is on verson 0.3
https://hackage.haskell.org/package/reflex-dom-0.3/docs/Reflex-Dom-Widget-Basic.html
I was told I could generate docs with haddock. I have the source code on my computer (using git clone) version 0.4
The haddock web page was way too advanced.
For the beginner, once I am in my directory, how do I generate docs?
Thanks to one of the answer I made come progress, but here is an error message:
src/Reflex/Dom/Xhr.hs:154:0:
error: missing binary operator before token "("
#if MIN_VERSION_aeson(1,0,0)
^

cabal haddock or stack haddock.

Once you have installed haddock, you can run it as follows:
haddock --html -o <haddock-folder> <list-of-haskell-files>
So for instance:
haddock --html -o the_documentation *.hs
will generate the documentation of all the Haskell files in that directory (not any subdirectories) in a directory named the_documentation.
Some shells allow **.hs to look for all .hs files (subdirectories included). So you might try:
haddock --html -o the_documentation **.hs
If the shell does not suport that, you can of course use a combination of find and xargs, like:
find -iname '*.hs' | xargs haddock --html -o the_documentation
Here find will generate a list of all files that end with .hs, and xargs will write all these files as parameters to haddock --html ....

Related

Pattern syntax %.3: man/libfoo.man in Automake with different base name

I wrote a library libfoo providing functions bar and baz.
I want the user to be able to find the same man-page (from mans/libfoo.man) when they call man libfoo, man bar and man baz (Similar to man fprintf, man sprintf all pointing to the same page.)
My current setup has the files mans/libfoo.man and Makefile.am
To 'tell' automake that I want to end up with the three man-pages I specified the dist_man3_MANS variable.
Makefile.am:
dist_man3_MANS = mans/libfoo.3 mans/bar.3 mans/baz.3
Coming from GNU make, I thought I could just write
%.3: mans/libfoo.man
ln -S libfoo.man $#
to create links temporarily and then let Automake install those accordingly, but Automake errors out with Makefile.am:115: warning: '%'-style pattern rules are a GNU make extension. I want to do it properly and take this warning seriously by not relying on GNU Make to be as portable as possible.
The Automake manual suggests to add a target
.man.3:
$(LN_S) $^ $#
but that just tells Automake that xx.man can be compiled to xx.3, requiring the base name to be the same. I don't want to carry around those xx.man files, so this approach does not work.
I could hack it in with putting a rule
dist_man3_MANS = mans/libfoo.3 mans/bar.3 mans/baz.3
$(dist_man3_MANS): mans/libfoo.man
$(LN_S) libfoo.man $#
but that seems like a dirty hack, because I am not giving it a recipe to compile .man to .3, but rather say: "Hey, you can create those files with this rule", which for this case may work coincidental.
I would follow the example from the Automake info page section Extending Automake Rules and do something along the lines of
LIBFOO_MAN_ALIASES = bar baz
install-data-hook:
set -e; \
cd $(DESTDIR)$(man3dir) && \
for manalias in $(LIBFOO_MAN_ALIASES); do \
$(LN_S) libfoo.3 $${manalias}.3; \
done
uninstall-hook:
cd $(DESTDIR)$(man3dir) && \
for manalias in $(LIBFOO_MAN_ALIASES); do \
rm -f $${manalias}.3; \
done
relying on AC_PROG_LN_S to make sure that $(LN_S) does something reasonable for the system (symlink, hardlink, copy) to create a file name which can be open(2)ed and read.
FTR, I have just taken a look at three different systems' man pages and found them using three different methods to make the fprintf(3) man page show the same man page as printf(3) does:
Debian 10 uses symlinks
Fedora 35 uses a /usr/share/man/man3/fprintf.3 file containing .so man3/printf.3 (while some other man pages use symlinks to achieve the same effect)
FreeBSD 13 uses hardlinks, and find /usr/share/man -type l does not find any symlinks on my relatively clean system. However, manually testing both symlinks and the .so man3/printf.3 method suggests that FreeBSD man(1) does not treat symlinks in any special way and therefore opens the symlinked man page, and it also interprets the .so command just like Fedora 35's man(1) does.
I do not know how portable each of those methods is. Each of these three methods could set up on make install by using an appropriate install-data-hook, but any man file which can be opened using open(2) appears to be work, and therefore $(LN_S) looks like a good bet.

symbol lookup error: undefined symbol: FT_Get_Font_Format

The error is
linux/FIT/fit: symbol lookup error: linux/FIT/fit: undefined symbol:
FT_Get_Font_Format
This is part of an Android build.
It doesn't tell me which .so it searched.
I searched for that symbol
sudo grep -F "FT_Get_Font_Format" / -r --include="*.so*"
And it's in a bunch of .so files.
QUESTION
How do I find out which .so file it's looking for?
It doesn't tell me which .so it searched.
It searched all of the loaded libraries.
Unlike on Windows, the UNIX linker doesn't record which symbol is provided by which library, and the loader searches all currently loaded libraries (in order of their loading) for all of the symbols it needs to resolve.
I searched for that symbol
sudo grep -F "FT_Get_Font_Format" / -r --include="*.so*"
That command does not distinguish between definition and references to the symbol, therefore this conclusion:
And it's in a bunch of .so files.
doesn't tell you anything useful.
The correct way to search for definition of the symbol would be:
find / -name '*.so*' -type f -print0 |
xargs -o nm -AD | egrep ' [TDW] FT_Get_Font_Format'
Or you can just google it, and discover that it's part of FreeType API, and should be in libfreetype.so.
This answer suggests that your version of freetype may be too old.

Ocamldoc "Unbound module Thread" without ocamlfind

Is it possible to use ocamldoc for a project with Threads without using ocamlfind? More importantly, how?
-thread or -package aren't supported by ocamldoc, and -I -thread doesn't work.
-thread or -package aren't supported by ocamldoc, and -I -thread doesn't work.
Try with -I +threads instead. This will tell ocamldoc where to look for the thread library files.
On a side note, I use ocamlbuild for generating documentation, when I am already using it for my project builds (which is most of the time). With this tool, you only need to list all the documented ml files in a single .odocl file, and ask for the corresponding .docdir/index.html with the same parameters as a compilation command to get the documentation generated. If your project compiles with ocamlbuild, it should be able to generate documentation without hiccups with it as well.
$ ls src
foo.ml bar.ml baz.zip
$ ls -1 src/*.ml | cut -f1 -d'.' > project.odocl
$ cat project.odocl
src/foo
src/bar
$ ocamlbuild project.docdir/index.html
[...]
$ ls project.docdir
Bar.html
Foo.html
index.html
[...]

Compiling static library for Google Native Client using SCons

I'm working on a few multi platform projects that all depend on common framework.
I want to add support for Google Native-Client (NaCl). The way I aproached the problem is first to compile the framework as static library (this is how I've been doing it on all other platforms).
I have to say that I have never used SCons before. I think I start grasping it. Starting from a build.scons from a tutorial I can get some code compiling and linking. Now I would want to skip the linking process but seems like the nacl_env was never intended to compile static libraries.
Reading the SCons help didn't help me much since the Library node is missing from the nacl_env.
I don't think I understand SCons enough to write the whole build process from scratch so I was hopping to not have to do so.
1. Am I approaching the problem correctly?
2. Any tips or sample nacl static libs, build using SCons?
Ok, what I did is way more trickery than what you probably need.
I wanted my static library to handle the initialization steps of the NaCl module, and then call some project-specific function.
I ended up turning my whole framework and the contents of the built-in libppapi_cpp.a into a single .o file, and then that into a single .a file, a static library.
I needed a single .o file, because otherwise I would run into dependency problems releated to initialization, I could not solve.
build_lib.sh (framework):
#!/bin/bash -e
SDK="/home/kalmi/ik/nacl_sdk/pepper_15"
function create_allIn_a {
TMPDIR="`mktemp -d`"
echo $TMPDIR
cp $O_FILES $TMPDIR
pushd $TMPDIR &> /dev/null
$AR x $LIBPPAPI_CPP_A
$LD -Ur * -o ALL.o
$AR rvs $OUTPUT_NAME ALL.o
$RANLIB $OUTPUT_NAME
popd &> /dev/null
}
./scons
BIN_BASE="$SDK/toolchain/linux_x86/bin"
LD="$BIN_BASE/i686-nacl-ld"
AR="$BIN_BASE/i686-nacl-ar"
RANLIB="$BIN_BASE/i686-nacl-ranlib"
LIBPPAPI_CPP_A="$SDK/toolchain/linux_x86_newlib/x86_64-nacl/lib32/libppapi_cpp.a"
O_FILES="`find $(pwd)/opt_x86_32 | grep .o$ | grep --invert-match my_main.o | tr "\n" " "`"
LIBDIR="../../../bin/lib/lib32"
mkdir -p $LIBDIR
if [ -f $LIBDIR/libweb2grid_framework.a ]; then
rm $LIBDIR/libweb2grid_framework.a
fi
OUTPUT_NAME="`readlink -m $LIBDIR/libweb2grid_framework.a`"
create_allIn_a
BIN_BASE="$SDK/toolchain/linux_x86/bin"
LD="$BIN_BASE/x86_64-nacl-ld"
AR="$BIN_BASE/x86_64-nacl-ar"
RANLIB="$BIN_BASE/x86_64-nacl-ranlib"
LIBPPAPI_CPP_A="$SDK/toolchain/linux_x86_newlib/x86_64-nacl/lib64/libppapi_cpp.a"
O_FILES="`find $(pwd)/opt_x86_64 | grep .o$ | grep --invert-match my_main.o | tr "\n" " "`"
LIBDIR="../../../bin/lib/lib64"
mkdir -p $LIBDIR
if [ -f $LIBDIR/libweb2grid_framework.a ]; then
rm $LIBDIR/libweb2grid_framework.a
fi
OUTPUT_NAME="`readlink -m $LIBDIR/libweb2grid_framework.a`"
create_allIn_a
./scons -c
The my_main.o file is excluded from the static library, because that file contains the function that is to be provided by the project that uses this framework.
The build.scons file for the framework is truly ordinary.
build.scons (for some project that uses this framework):
#! -*- python -*-
#What to compile:
sources = [ 'src/something.cpp', 'src/something_helper.cpp' ]
###############################################################x
import make_nacl_env
import nacl_utils
import os
nacl_env = make_nacl_env.NaClEnvironment(
use_c_plus_plus_libs=False,
nacl_platform=os.getenv('NACL_TARGET_PLATFORM'))
nacl_env.Append(
# Add a CPPPATH that enables the full-path #include directives, such as
# #include "examples/sine_synth/sine_synth.h"
CPPPATH=[os.path.dirname(os.path.dirname(os.path.dirname(os.getcwd())))],
LIBS=['web2grid_framework','srpc'],
LIBPATH=['../../../bin/lib/lib32','../../../bin/lib/lib64'],
LINKFLAGS=['-pthread']
)
nacl_env.AllNaClModules(sources, 'client')
Some lines worth highlighting:
use_c_plus_plus_libs=False,
LIBS=['web2grid_framework','srpc'],
LIBPATH=['../../../bin/lib/lib32','../../../bin/lib/lib64'],
LINKFLAGS=['-pthread']
I am not saying that this is a clean method, but it gets the job done.
So, there's two questions here
1. Using SCONS:
NaCl uses SCONS for it's examples, simply to help compiling of the examples easier. In reality, SCONS simply directs to the GCC/G++ compilers in the SDK build directories. (SCONS will take the input scripts, and create the final param string to send to GCC)
GCC is a common compiler, and is well documented on the net : http://gcc.gnu.org/
How you integrate NaCl compilation into your work-flow is up to you (ie you're not forced to use SCONS).
For instance, if you'd like to go to GCC directly, you can simply call :
<path to bin>/x86_64-nacl-gcc -m64 -o test.nexe main.c
For a more detailed look into how to compile NaCl modules, please read the documentation # gonacl.com on compiling which will detail how to compile with and without SCONS.
2.Compilng Static libs with GCC
Here is an example : http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
~Main

ld cannot find library that is installed

I'm sitting on an OpenSuse 11.1 x64 Box and I have a module that uses sigc++. When linking like this:
g++ [a lot of o's, L's and l's] -lsigc-2.0
I get
/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: cannot find -lsigc-2.0
However the library is there.
In the filesystem:
$ sudo find / -name "libsigc-2.0*"
/usr/lib64/libsigc-2.0.so.0.0.0
/usr/lib64/libsigc-2.0.so.0
/usr/lib64/libsigc-2.0.so
In ld.so.conf I have:
/usr/lib64
And when invoking ldconfig:
$ ldconfig -v | grep sigc
libsigc-2.0.so.0 -> libsigc-2.0.so.0.0.0
Why?
I'm so dumb. It's an old codebase and just before the -lsigc-2.0 statement I had a
-Wl,-Bstatic
Obviously, there are no static librarys for libsigc (anymore).
It is possible that libsigc-2.0.so was linked with an SONAME other than libsigc-2.0.
objdump -p /usr/lib64/libsigc-2.0.so | grep SONAME
If you see something unexpected, e.g. libsigc, you may need to create an additional symlink with that name.

Resources