Compiling custom ejabberd with multiple source files - module

I'm trying to compile custom ejabberd module which has multiple files in src/ and include/.
My module is conforming to https://github.com/processone/ejabberd-contrib guidelines and using ejabberdctl module_check produces "ok".
When I'm compiling and installing module with only one source, everything works as expected and ejabberdctl module_install installs module.
But when I have multiple source files, ejabberdctl module_install doesn't compile anything but file with exact name of my module.
I want to avoid manual compilation and rebar if possible. So my question is how to configure my module and where so that ejabberdctl module_install can build and install my module.
If that is not possible could you point me to some rebar script that can serve that purpose.
And finally can someone point me to some resource that explains why Erlang/OTP projects seem to have rigid file structure (I'm coming form c++ world and there IMO, tools and projects are way more forgiving in respect to file structure)
Details:
Erlang 18
ejabberd 15.11.120 (built from source)

if you install module by "ejabberdctl" you don't have to config in ejabberd.yml
other way is install module with source, you must copy file beam to lib/ejabberd... and config file config like README.TXT

Related

Install files using symbolic links with CMAKE

I have converted my project to use cmake. During development I'd like to be able to install the product not the normal way, but let (notably) the installed data files be symbolic links to the source tree.
The project is SWI-Prolog which provides functionality to directly navigate and edit source files. If I use this to extend and fix the system libraries however I'm editing the installed copy that I then need to copy back to the sources before I can commit.
I know I can override functions in cmake, but in this case we are dealing with cmake code that is generated.

Where to install FindLib.cmake

I'm creating a library (called fmi2) which I intend to install on my local machine (via a package manager) and then link to with a bunch of other libraries.
I'll be providing a Findfmi2.cmake file so that I can call find_package(fmi2) from my other libraries, but where should this file be conventionally installed?
Here are some choices I've considered and their problems:
/usr/share/cmake-3.8/Modules/Findfmi2.cmake
Advantage: find_package(fmi2) will just work
Disadvantage: Only works for one version of cmake
/usr/share/cmake/Modules/Findfmi2.cmake
Advantage: Should work for any version of cmake
Disadvantage: This is not a default folder. We would need to add set(CMAKE_MODULES_PATH /usr/share/cmake/Modules) and this kills any portability.
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Findfmi2.cmake
Advantage: Portable, just need to add set(CMAKE_MODULES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
Disadvantage: Not system-wide. Need to manually add this file to each library that uses it. This duplicates files in my framework.
You are authoring content in CMake. You don't need a FindModule. That is designed to find external non-CMake outputs.
This Stackoverflow post from ruslo should help you understand the difference between find_package() module mode and config mode. It also answers your question about paths for FindModules, i.e. they are copied into your CMake project, not discovered system-wide, unless they are part of the official FindModules bundled with CMake in the "Modules" directory.
Modern CMake documentation now finally contains good examples to create a config mode package: cmake-packages
If you want explicit full examples, though using slightly older syntax for the config.cmake files, ruslo has more on Github.

How to setup CLion to use waf as build system

I am trying to configure my Intellij Clion IDE for working with ns-3. Since ns-3 is using waf, it is more tricky than i thought and would be really happy to hear any advice
CLion supports compilation databases for quite some while, which waf, luckily, is able to generate using the clang_compilation_database extension.
You'll need to load it within your configuration and option step; i.e. like this:
def options(ctx):
# Assuming you just copied the script into a directory called tools
ctx.load('clang_compilation_database', tooldir='tools')
# ...
def configure(ctx):
ctx.load('clang_compilation_database', tooldir='tools')
# ...
Now you can call waf clangdb; you'll be presented a file called 'compile_commands.json' in your build directory.
CLion only uses cmake for its internal project definition - so you have to have a cmake config.
It can be very simple and mirror parts of another build system you actually use, but how CLion treats files and what it does when you tell it to build something is defined by cmake and only cmake.
You could setup compilation databases as suggested by Julian or you could try my fork, if you don't mind using a not completely up-to-date fork of the upstream project. https://github.com/Gabrielcarvfer/NS3.
Visual Studio can also be used with CMake projects and WSL, but ClangCL/MSVC support is being worked on.
I plan on opening a MR to upstream the CMake support, but it is a lot of work to replace Waf completely.

Empty ${shlibs:Depends} while packaging a Mapnik plugin with cmake-based build system for Debian/Ubuntu

I am creating a Mapnik plugin (https://github.com/rbuch703/coords-mapnik-plugin), and am currently working on packaging it for Debian/Ubuntu. The binary package consists of only a single shared library that is built from C++ code. But being a Mapnik plugin, this library follows conventions quite different from the usual POSIX library conventions:
the file name has to be <name>.input instead of lib<name>.so
the file is installed in the Mapnik plugin directory (usually /usr/lib/mapnik/input)
the file is not supposed to be found by ldconfig, but rather Mapnik tries to find the plugin by itself at runtime
Now the plugin's build system is cmake, which makes most parts of Debian packaging straight-forward: the debian/rules file contains only the basic lines:
#!/usr/bin/make -f
%:
dh $#
However, I am running into problems with the substitution variable {shlibs:Depends}: it is simply not set (in particular, there is no corresponding line in the debian/<package name>.substvars file), and Lintian rightly complains about that fact (Lintian's actual complaint is missing-dependency-on-libc. But when I manually add a libc dependency, Lintian explains package-depends-on-hardcoded-libc, which means "The given package declares a dependency on libc directly instead of using ${shlibs:Depends} in its debian/control stanza."). I would like to satisfy Lintian in than respect, but are unable to do so.
Now I found that I could add the line
dpkg-shlibdeps debian/<packagename>/usr/lib/mapnik/input/coords.input
to my rules file. That will create the correct ${shlibs:Depends} line, but it will create it in the wrong file (debian/substvars instead of debian/<package name>.substvars), where the build system simply ignores it and Lintian keeps complaining about missing dependencies.
I am guessing that the root of my problem is that my Mapnik plugin does not conform to the POSIX library naming conventions (and as a Mapnik plugin cannot do so), and thus the packaging system does not handle it correctly. But I am at a loss as to how to fix this problem.
Additional notes:
the packages are built using debuild. Apart from the Lintian error messages, the build process work fine and correctly creates the .deb package.
my practical goal is for the package to build cleanly on Launchpad, so that I can add it to my Ubuntu PPA.
you can provide an output file for dpkg-shlibdeps with the -T flag.
something like:
override_dh_shlibdeps:
dh_shlibdeps
dpkg-shlibdeps \
-Tdebian/<packagename>.substvars \
debian/<packagename>/usr/lib/mapnik/input/coords.input
if there are multiple *.input files, you could also do something like:
override_dh_shlibdeps:
dh_shlibdeps
find debian/<packagename>/ -name "*.input" -exec \
dpkg-shlibdeps -Tdebian/<packagename>.substvars {} +

Where to place a shared utility module in OCaml?

I have a file Tools.ml which contains some common utility functions I write myself. Under .../Code/ I have several folders which each contains a project. My question is where I should place this Tools.ml such that all the folders and files under .../Code/ could share this module by Open Tools.
Hope my question is clear... Does anyone have a good solution?
Edit1: Following #gasche's answer, I have written tools.ml as follows:
module Tools =
struct
let a_function = ...
...
end
Then I compiled it, and done ocamlfind install tools META tools.cmo tools.cmx tools.ml as suggested, which looks going well. Then I have written test.ml as follows:
open Tools
let f = Tools.a_function
then I compiled it with ocamlc test.ml -o test, then I got an error:
File "test.ml", line 1, characters 0-1:
Error: Error while linking test.cmo:
Reference to undefined global `Tools'
Could anyone tell me what happened?
You could package it as an independent library, install it with other OCaml libraries, and access to it, from your project, as a library.
A very simple way to do this is to write a META file for ocamlfind. Create a directory somewhere you're comfortable to hold you "personal library" project. Suppose you have tools.ml and tools.mli, and your code depends on some findlib package (eg. unix and bigarray). You META would look like this:
name="tools"
description="personal collection of utilities"
version="0.1"
requires="unix,bigarray"
archive(byte)="tools.cmo"
archive(native)="tools.cmx"
Once you have written this META file, it is easy to ask ocamlfind to "install" the library (and remove it if you want to), and use it in your other projects. To install, the syntax is ocamlfind install <name> <meta-file> <file1> <file2> ... where <file1>, <file2>.. are the file you wish to see included in the installation directory. You must at least have tools.cmi tools.cmo (and tools.o and tools.cmx for native compilation), but it is good practice to also have tools.mli for example (and, if you want to provide the code, tools.ml).
ocamlfind install tools META tools.cmi tools.cmo tools.o tools.cmx tools.mli
(Of course tools.cmo etc. have to exist, that is you must install after you have compiled your package. If you have used ocamlbuild, they are likely to be in a _build subdirectory, so ocamlfind install ... _build/tools.cmo ....)
From your numerous projects, you can use your library easily, either using the ocamlfind toold directly if this is what you already do to compile your programs
ocamlfind ocamlc -package tools ....
or through the facilities provided by ocamlbuild for example, adding package(tools) to your tags.
To reinstall your library if you made a change to it and want it accessible from your projects
ocamlfind remove tools
ocamlfind install tools META ...
You could also handle all this through oasis, which is a layer on top of ocamlfind/ocamlbuild to automate this process. I'm not familiar enough with oasis to give such examples off the top of my head, but it should be equally simple for such a restricted case (one-file library), and scale better if you wish later to extend your library (eg. it can also handle documentation generation, pre-compilation configuration...).