OMake bin directory - ocaml

I am trying to have omake build stuff in my bin directory. I tried
LIB = ../bin/mylib
.DEFAULT: $(OCamlLibrary $(LIB), $(FILES))
But only the .a and .cmxa end up in bin, all the .cmx .cmi and .o end up in src. What am I doing wrong?

Nothing wrong. OMake's built-in OCaml related rules compile each module and produce its objects (.cmo, .cmi, .cmx and .o) in the same directory of the source code.
$(OCamlLibrary $(LIB), $(FILES)) function link these module objects and produce library files $(LIB).cma, $(LIB).cmxa and $(LIB).a, just like you have seen.
If you want to change the destination directory of object files, you have to fix the build rules for OCaml. They are defined in OCaml.om found in OMake's library directory, but I have to say that this is very challenging.

Related

File path issue with Meson and Eigen

I cannot make local include paths work in the Meson build system.
This C++ inclusion works correctly:
#include </cygdrive/c/Users/user/project/Third-Party/eigen/Eigen/Dense>
This one does not:
#include "Third-Party/eigen/Eigen/Dense"
fatal error: Eigen/Dense: No such file or directory
In the Meson build file, I tried to add Eigen's path, without success:
# '.' will refer to current build directory
include_dirs = include_directories('include', '.', '../project/Third-Party/eigen')
This is the project tree structure:
project
meson.build
src
meson.build
example.h
example.cpp
Third-Party
eigen (headers only lib)
Eigen
Note: with CMake I do not have this issue.
For dependency management, meson allows you to manually declare include_directories() in your build files. However, there is another way do handle dependencies: using dependency() command.
dependency() is a much better way to handle dependencies, because meson will build it if necessary (if dependency is a shared or a static library) and safely allows you to use includes. That means that you don't have to know where includes for dependency are located physically or care about their paths ever after. The only downside is that this kind of dependency needs it's own meson.build file.
Using dependency() command:
To actually use it, you have to write a wrap file for dependency. Or, if you are lucky enough, there is already a wrap file for you in the Wrap DB -- a community-driven database for meson wrap files. Wrap file is a config of some kind that declare where you can get a dependency and in what form. Wrap file can wrap around zip archives and git repositories.
For your given dependency, there is wrap file in Wrap DB: eigen. All you have to do is download it and place it in the subprojects directory near your meson.build. For example:
$ cd project
$ mkdir subprojects
$ wget "https://wrapdb.mesonbuild.com/v1/projects/eigen/3.3.4/1/get_wrap" \
-O subprojects/eigen.wrap
Now, not every project builds with meson. For the ones that don't, wrap file also specify a patch. Patch is used to just copy appropriate meson.build file into dependency directory (as well as any other files that would be needed for building that particular dependency with meson). Eigen wrap file contains a patch.
To find out how any particular dependency declare itself as a dependency (using declare_dependency() command), you need to investigate meson.build file in dependency source directory (although it's often just name of the dependency plus _dep, e.g. "eigen_dep"). For me, eigen directory was subprojects/eigen-eigen-5a0156e40feb. So, you search for the declare_dependency() command:
$ grep declare_dependency subprojects/eigen-eigen-5a0156e40feb/meson.build
eigen_dep = declare_dependency(
As you can see, eigen declare dependency as eigen_dep. If you want to know what exactly is declared, just scroll down the dependency meson.build file.
Now, to use that eigen_dep in your project, create a dependency object with a dependency() command. Here is a sample project that I used to compile "A simple first program" from Eigen: Getting Started:
project('example', 'cpp')
eigen_dependency = dependency('eigen', fallback: ['eigen', 'eigen_dep'])
executable('example', 'example.cpp', dependencies: eigen_dependency)
Notice arguments for the dependency() command. The first one is system-wide dependency that meson is searching for. If there is no eigen for development installed in your system, then meson uses fallback: first item in fallback is basename of the wrap file, second item is a name of declared dependency.
Then use eigen_dependency variable in whatever you build, passing it to the dependencies argument.
Using include_directories() command:
If you want to just include some files from external directory (such as your "Third-Party" directory) using include_directories() command, that directory has to be relative to the meson.build file where you use it.
To use manually declared includes, you need to call include_directories() command to get the include_directories object. Pass that object to include_directories argument in whatever you build.
Given your example, I assume that root meson.build file is a project build file. Then in that root meson.build, for example, you can write:
# File: project/meson.build
project('example', 'cpp')
eigen_includes = include_directories('Third-Parties/eigen')
executable('example', 'example.cpp', include_directories: eigen_includes)
But if you want to get eigen includes from src/meson.build, then you need to change include_directories to:
# File: project/src/meson.build
eigen_includes = include_directories('../Third-Parties/eigen')
...

Set C++ object file output location with CMake

I would like to use CMake for a project, but I have the following two requirements:
The final output of the project should be a set of object files (*.o).
The location of the object files is important. I want to select which directory the files are outputted.
Does CMake support this type of behavior? If so, how? Can I do it with move commands after the object file is build?
First create an object library.
Now the problem is that:
Object libraries cannot be imported, exported, installed, or linked.
http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:add_library
I would try to use the install(DIRECTORY ...).
Using the options:
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} #Probably you have to check more precisely where the object files are built
DESTINATION #it's something relative to DESTDIR, if set, or CMAKE_INSTALL_PREFIX otherwise
FILES_MATCHING
PATTERN "*.o"
A flaw of this solution will be in the output directory name, that will be basically decided by cmake, I wonder if anything can be done in that respect.

CMake Difference between include_directories and add_subdirectory?

I'm learning CMake for building C++ code, and struggling with the following concept. On my root level directory I have some cpp files and a CMakeLists.txt that succesfully generates some thrift code in a gen-cpp directory. My root level CMakeLists.txt contains :
include_directories("path-to-root"/gen-cpp). (along with the relevant thrift auto-generating and includes.
Everything compiles ok but I get run time dynamic library linked errors for undefined symbol referencing a class defined in the gen-cpp directory. When I move the files in the directory to the root level, it runs fine. what am I missing? (I had also adjusted the #include in the root level cpp directorie s to point to "path-to-root"/gen-cpp).
Is this a misunderstanding of using include_directory, where I should be using add_subdirectory. If the latter, would the code in gen-cpp needs its own CMakeLists.txt? Why is this additional file not needed, when the contents of said directory are root level?
add_subdirectory(source_dir): Used to add a subdirectory to the build. There is also a CMakeLists.txt file in the source_dir. This CMakeLists.txt file in the specified source directory will be processed immediately by CMake before processing in the current input file continues beyond this command.
include_directories(dir): Add the given directories to those the compiler uses to search for include files. These directories are added to the directory property INCLUDE_DIRECTORIES for the current CMakeLists file.
The include_directories() is used for adding headers search paths (-I flag) and add_subdirectory() will make no difference in this case.
I suppose, you need to list *.cpp files from gen-cpp folder in add_executable() or add_library() calls, in which you wish these symbols to be.
Alternatively, you can compile all thrift sources into the library and link it with your code.

How to compile multiple files in ROOT

I wrote a C++ program (with a main.cpp, and various header and implementation files) that compiles fine under g++. Now I am trying to compile it in Cern's ROOT library, but I do not know how to, since the only way I know how to compile files in ROOT is by using .L main.cpp.
How can I include multiple files in ROOT?
The most reliable way to use ROOT (at least historically and currently) is to ignore the interpreter other than for the simplest explorations and explicitly compile your C++ programs against the ROOT libraries. For example, use
g++ MySource.cc `root-config --libs --cflags` -o foo
to compile an executable "foo" from a single source file. For more info on that helper script run "root-config --help".
Multi-file programs/libraries are nothing special provided that you supply the required args to point at the ROOT libraries and headers (and that the libs are available in LD_LIBRARY_PATH at runtime.) Standard C++ guides will explain that step if needed. You can safely put this into a makefile, too.
For my money this is both easier and more reliable than using the .L etc. commands in the CINT interpreter. Last time I tried, ACLiC was actually compiling against a temporary (and mangled) version of the specified source file, so any error messages from the compiler were pretty much useless!
I use CMake to compile my ROOT-based projects.
If you have a project directory proj/ and it contains src/ and bin/, you'll need 3 CMakeList.txt files, one in each directory.
A simple example CMakeList.txt in the main project directory:
cmake_minimum_required(VERSION 2.6)
project (SOME_PROJ_NAME)
add_subdirectory(src)
add_subdirectory(bin)
src/ directory is where you keep your .h and .cxx proj. library files. Example CMakeList.txt file:
# get all the *.cxx filenames, to compile them into a lib
file(GLOB SOME_PROJ_LIB_SRCS "${PROJECT_SOURCE_DIR}/src/*.cxx")
# include ROOT library and include files
include_directories(/path/to/root/dir/include/dir)
link_directories(/path/to/root/dir/lib/dir)
# and compile src into a library
add_library(Proj_lib_name ${SOME_PROJ_LIB_SRCS})
# here, list the ROOT libraries you require
target_link_libraries(Proj_lib_name dl Core Cint RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread Gui pthread m)
bin/ directory is where you keep your app .cxx files and it has a CMakeList.txt file:
include_directories(${PROJECT_SOURCE_DIR}/src)
link_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(/path/to/root/dir/include/dir)
link_directories(/path/to/root/dir/lib/dir)
add_executable(example_app.exe example_app.cxx)
target_link_libraries(example_app.exe Proj_lib_name dl Core Cint RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread Gui pthread m)
Finally, to compile ROOT-based code with CMake, out of source, you create a "build" dir in your top level project dir, so that your dir structure looks like this:
proj/
bin/
build/
src/
Then
cd build
cmake ..
Your binaries will be located in build/bin/ directory
Hope this helps.
It appears that I would simply .L <filename> for each file I want, since .L tells ROOT to "load the contents of file in memory." Though now I am not too sure which order to load the files in, as they are giving me errors.

How do I link against libtool static la library?

I have compiled this library successfully. It generates a libcds2.la file that I am trying to link into my own project. I have all files (including the .h file) in the same directory as my project file. When I try to link and use the functions of said library, using:
g++ -o test -I/opt/include/ -L/opt/lib/ -lcds2 libcdsNoptrs.cpp util.cpp
comes back with
./test: error while loading shared libraries: libcds2.so.2:
cannot open shared object file: No such file or directory
whatever that is. But the point is that most of the time it just doesn't recognize the library. I assume I'm doing something wrong with the file paths, but can't figure it out. My test file is a C++ file including #include "libcds2/array.h" and everything is installed in opt/lib, opt/include, ugly, I know, but that's what the Makefile generated.
Any pointers?
The libtool .la is a 'meta data' file. After building the cds2 library, it's expected that libtool will also be used in 'link' mode to build any of the package's tests, etc.
Typically, the in the directory you find the .la file, you will find the .a and .so under the .libs subdirectory. The .libs/libcds2.a file will be found there, provided configure was given the --enable-static option (or it is enabled by default). But, my understanding is that you've installed the package in /opt :
g++ -I/opt/include/ libcdsNoptrs.cpp util.cpp -o test /opt/lib/libcds2.a
Otherwise, if libcds2 isn't installed, just supply a path to: .../libcds2/lib/.libs/libcds2.a
Unless you want to use libtool in --link mode with -static to handle everything. But learning the advantages of libtool is usually an exercise for a rainy day:)