Linking to Armadillo libraries with CMake - linker

I am trying to install MLPack on windows 8.
I configure the CMakeLists.txt file with:
set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")
Then when I ran CMake I had a whole series of warning like these ones:
WARNING: Target "mlpack" requests linking to directory "C:\Program Files (x86)\armadillo\lib". Targets may link only to libraries. CMake is dropping the item.
In \mlpack-1.0.4\src\mlpack directory I found another CMakeLists file with:
target_link_libraries(mlpack
${ARMADILLO_LIBRARIES}
${Boost_LIBRARIES}
${LIBXML2_LIBRARIES}
)
that I changed to (not sure if that was a good idea):
target_link_libraries(mlpack
${Boost_LIBRARIES}
)
link_directories(mlpack
${ARMADILLO_LIBRARIES}
${LIBXML2_LIBRARIES}
)
then CMake seems to be running smoothly:
-- Found Armadillo: C:\Program Files (x86)\armadillo\lib (found suitable version "3.800.2", minimum required is "2.4.2")
-- Found LibXml2: C:\cpp\libraries\libxml2-2.7.8.win32\lib (found suitable version "2.7.8", minimum required is "2.6.0")
-- Boost version: 1.53.0
-- Found the following Boost libraries:
-- program_options
-- unit_test_framework
-- Boost version: 1.53.0
-- Found the following Boost libraries:
-- random
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Configuring done
-- Generating done
-- Build files have been written to: C:/cpp/libraries/mlpack-1.0.4
but now when running make I have tons of such errors :
Linking CXX executable ..\..\..\..\gmm.exe
CMakeFiles\gmm.dir/objects.a(gmm_main.cpp.obj):gmm_main.cpp:(.text+0xb9): undefined reference to `wrapper_dgemv_'
CMakeFiles\gmm.dir/objects.a(gmm_main.cpp.obj):gmm_main.cpp:(.text$_ZN4arma6auxlib10det_lapackIdEET_RKNS_3MatIS2_EEb[__ZN4arma6auxlib10det_lapackIdEET_RKNS_3MatIS2_EEb]+0x115): undefined reference to `wrapper_dgetrf_'
which after investigation seems to be related to Armadillo.
Any idea what is happening ? I guess I should use target_link_libraries for Armadillo but I am not sure how.

The issue is hopefully pretty easy to resolve. When you do this...
set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")
you're effectively short-circuiting the find_package(Armadillo 2.4.2 REQUIRED) call, since it expects to have to do the work to find these paths. However, when find_package does the work, the variable ARMADILLO_LIBRARY gets set to the path to the library itself - not the path to the lib's directory.
So the problem boils down to setting ARMADILLO_LIBRARY to the path to the lib's directory rather than the lib itself. This ultimately yields a linker error since the target gmm (added in src\mlpack\methods\gmm\CMakeLists.txt) links to mlpack, and mlpack has been set to link to ${ARMADILLO_LIBRARIES}, which isn't set correctly.
It turns out that find_package(Armadillo ...) already checks in "$ENV{ProgramFiles}/Armadillo/lib" and "$ENV{ProgramFiles}/Armadillo/include", and I expect these resolve to "C:\\Program Files (x86)\\armadillo\\lib" and "C:\\Program Files (x86)\\armadillo\\include" on your machine.
So to fix this, you should delete the lines setting ARMADILLO_LIBRARY and ARMADILLO_INCLUDE_DIR, and revert your change in src\mlpack\CMakeLists.txt (using link_directories is generally a bad idea anyway).
After making these changes, you should delete at least your CMakeCache.txt (in the root of your build tree), or even your entire build tree before re-running CMake to avoid the possibility of using bad cached values from previous failed attempts.

I realize this is a late answer, and I hope you have it figured out by now. Even so, I believe your issue is that the ARMADILLO_LIBRARY variable should hold the exact location of the library, instead of the directory the library is in. So, maybe this would work:
set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib\\armadillo.lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")
The variable LIBXML2_LIBRARIES should also contain the actual path of libxml2.lib (or whatever the actual library is called).
Have you seen this page of instructions I wrote a while back for compiling mlpack on Windows?
http://www.mlpack.org/trac/wiki/MLPACKOnWindows
Feel free to file a bug report on Trac if you have further problems in the future. I only stumbled upon this by chance, so I don't monitor Stack Overflow for issues.

I ran into the same problem. There are two bullets aramadillo library faq which ask you to uncomment the lines
#define ARMA_USE_LAPACK
#define ARMA_USE_WRAPPER
in the file
include/armadillo_bits/config.hpp
which is in the armadillo source tree.
When you recompile after uncommenting the lines, you can see the symbols in the armadillo shared library/dll. Hope this helps!

Related

Shows Missing library : ff while building echidna using stack install

I am trying to build echidna using stack install.
https://github.com/crytic/echidna
I am continuously getting the missing library error while installing at a progress state of 171/178.
I believe it to be more of stack error than library error. Error shown is as follows
I have tried installing the library but not getting any C library of such sort.ye
SO, i've installed every library using
sudo apt-get install lib*ff*-dev
isn't working yet.
-- While building package hevm-0.31 using:
/home/aman/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3 --builddir=.stack-work/dist/x86_64-linux/Cabal-2.2.0.1 configure --with-ghc=/home/aman/.stack/programs/x86_64-linux/ghc-8.4.3/bin/ghc --with-ghc-pkg=/home/aman/.stack/programs/x86_64-linux/ghc-8.4.3/bin/ghc-pkg --user --package-db=clear --package-db=global --package-db=/home/aman/.stack/snapshots/x86_64-linux/lts-12.10/8.4.3/pkgdb --package-db=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/pkgdb --libdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/lib --bindir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/bin --datadir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/share --libexecdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/libexec --sysconfdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/etc --docdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --htmldir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --haddockdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --dependency=QuickCheck=QuickCheck-2.11.3-3XHQpBYb83U2mMvNz2AjQX --dependency=abstract-par=abstract-par-0.3.3-Ie3MD7O3orK6ZR8i7FuBEv --dependency=aeson=aeson-1.3.1.1-7JlrwYHW7OR9ca4RRZ9oOf --dependency=ansi-wl-pprint=ansi-wl-pprint-0.6.8.2-9fh9v74MJQDJeSHE7X3Co6 --dependency=async=async-2.2.1-7DQr5PBcpiwJNOuf7ZiSPa --dependency=base=base-4.11.1.0 --dependency=base16-bytestring=base16-bytestring-0.1.1.6-I0igvRcEwRNBMqqPC2yQBh --dependency=base64-bytestring=base64-bytestring-1.0.0.1-4OCIe2BZn8jKI191JIXI37 --dependency=binary=binary-0.8.5.1 --dependency=brick=brick-0.37.2-HmDqAExuwtV4o98FRmS9eK --dependency=bytestring=bytestring-0.10.8.2 --dependency=cereal=cereal-0.5.7.0-ILaYAmVTyR1IcEsGXXUCfI --dependency=containers=containers-0.5.11.0 --dependency=cryptonite=cryptonite-0.25-GgyZs9E1viv2owjaLxA3vq --dependency=data-dword=data-dword-0.3.1.2-CMzWV6RCGtK8L6wsVSErKS --dependency=deepseq=deepseq-1.4.3.0 --dependency=directory=directory-1.3.1.5 --dependency=fgl=fgl-5.6.0.0-E3fRSNebqkULRqplV3ljSc --dependency=filepath=filepath-1.4.2 --dependency=ghci-pretty=ghci-pretty-0.0.2-I5PJbL8ge6MChp3KxZbHqH --dependency=haskeline=haskeline-0.7.4.3-5EI2v7Zmtnz57a7mmnEGOS --dependency=lens=lens-4.16.1-B0f4CyKKTUGAKBzzY965AX --dependency=lens-aeson=lens-aeson-1.0.2-Jly9eqrxMbj6GutGwOKn69 --dependency=megaparsec=megaparsec-6.5.0-G48ltiRFbVUHATB1lTnNRx --dependency=memory=memory-0.14.16-GTCi0eCrvrnI3inLDBWVMK --dependency=monad-par=monad-par-0.3.4.8-Jjk0JT5qYVK4xEO13GFUu8 --dependency=mtl=mtl-2.2.2 --dependency=multiset=multiset-0.3.4.1-DOPR5uXspss8vZY4jdOdOo --dependency=operational=operational-0.2.3.5-4jEcCWo4nKu1T4LZlKqe58 --dependency=optparse-generic=optparse-generic-1.3.0-1jcIewFKPXBLcRetZisV2l --dependency=process=process-1.6.3.0 --dependency=quickcheck-text=quickcheck-text-0.1.2.1-2lR7Kay7WBV5AMKAdKDpZZ --dependency=regex-tdfa=regex-tdfa-1.2.3.1-9PkkapJrmiKFVG38JA02jN --dependency=restless-git=restless-git-0.7-83nBoDMPYLtJIx01bvXzKs --dependency=rosezipper=rosezipper-0.2-GAlMD5j8Qb83GzjCYQknnx --dependency=s-cargot=s-cargot-0.1.4.0-J9AhWfrUxDQ6YMTyzXkHth --dependency=scientific=scientific-0.3.6.2-5di0UflhS5I1xpiiCPzjKz --dependency=semver-range=semver-range-0.2.7-dBvW3ofcsgDQf0zazTsJd --dependency=temporary=temporary-1.3-5Z6bOFbSCb7VhnH5UnI2r --dependency=text=text-1.2.3.0 --dependency=text-format=text-format-0.3.2-Fd261TSu6ptAAzilVN6BFx --dependency=time=time-1.8.0.2 --dependency=transformers=transformers-0.5.5.0 --dependency=tree-view=tree-view-0.5-Kkrk0dCM0oj2Q4xwPbd7Gg --dependency=unordered-containers=unordered-containers-0.2.9.0-IkfpzvG0LzrHAbTzfMidvY --dependency=vector=vector-0.12.0.1-4awQG9XUvVEBfJgKGHBhOb --dependency=vty=vty-5.21-A2OCwk39Wv3J3RjR3BvHey --dependency=witherable=witherable-0.2-2RYbFmOnVolGAqiDDS1CLe --dependency=wreq=wreq-0.5.2.1-IjuXB0jwsxA7O3uIVjcJXu --extra-include-dirs=/home/aman/Downloads/Compressed/ff13c/source/ --extra-include-dirs=/usr/local/opt/readline/include --extra-lib-dirs=/usr/local/opt/readline/lib
Process exited with code: ExitFailure 1
Logs have been written to: /home/aman/Desktop/new/echidna2/echidna/.stack-work/logs/hevm-0.31.log
Configuring hevm-0.31...
Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3: Missing dependency on a foreign
library:
* Missing (or bad) C library: ff
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.If the
library file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
The stack install must find this library and end up successfully installing the library I'm using.
So, it is clear from the error provided above, that the installation was not able to find the libff file.
The best solution is to build the libff library manually and copy the required builds at the place it should be.
The best way to debug the problem is to look at the executed command closely and try to find the possible places where the libff should be...
Looking into the very 2nd error line, i.e. the complete command it was trying to execute
here, I sighted the following options being executed
--extra-include-dirs=/usr/local/opt/readline/include --extra-lib-dirs=/usr/local/opt/readline/lib
In order to solve this, I looked for the required libff library and cloned it from GitHub. I cloned the required dependencies and places them in the directory it should be.
https://github.com/scipr-lab/libff
I then followed the "Build guide" to build the required library.
Then with the superuser on, I created the directories, /usr/local/opt/readline/lib and /usr/local/opt/readline/include, and it was solved. And pasted the required builds in it.
Used stack install again, and it worked.
Note:
I thought many beginners may have similar problem while installing the required tools for their use. These small ideas may help them.

GDB - read.c: No such file or directory [duplicate]

I wanted to debug printf function, so when I step inside the printf function (gdb debugger) it showed me this:
__printf (format=0x80484d0 " my name is Adam") at printf.c:28
28 printf.c: No such file or directory.
What is the meaning of this?
And when I again started step then there are a lot more statements like this.
Please help me to understand this.
I think it's pretty clear. There is a place where the gdb expects the source code to be, so download glibc's source code and put it there. I think the error message contains the full path.
If it's a linux distro it's fairly simple in fact because usually source packages are shipped too. Otherwise you need to find the source code yourself, note that it MUST be exactly the same that was used to compile the c library components, not just the same version because distributors often make changes to the sources.
Well, for the debugger to show you the code that was compiled into the binaries you're using, you need the original code somewhere.
You don't seem to have that, so your debugger can't find it.
Notice that you usually do not want to debug the source code of your std library functions, but only the way they are being called. For that, the usual "debug symbol" packages of your operating systems are optimal.
As others have answered, GDB was unable to find the source file.
For the C runtime libraries, Linux distributions may provide a debuginfo RPM that you can install, which may allow GDB to view the files. For example:
$ yum search glibc-debuginfo
...
glibc-debuginfo.x86_64 : Debug information for package glibc
glibc-debuginfo-common.x86_64 : Debug information for package glibc
...
The glibc package and the glibc-debuginfo are a matched pair. There is no explicit dependency, but glibc-debuginfo package won't work unless it is matched with the same version of glibc.
If you have the sources unpacked somewhere, but not where GDB is expecting them to be, you can attempt to use either the directory or the set substitute-path command to let GDB know where the sources are.
The directory command tells GDB to prepend a prefix ahead of any source file path it is attempting to find. For example, if the source tree is actually located under the /tmp, you could use:
(gdb) directory /tmp
The set substitute-path command is used to tell GDB to replace a matching prefix in a source file path with a different path prefix. For example, if the compiled source file was in /build/path/source.c, but in debugging the source file is actually in /usr/home/alice/release-1.1/source.c, then you could use:
(gdb) set substitute-path /build/path /usr/home/alice/release-1.1
The command assumes that you are only specifying a complete path names, so it won't perform the substitution on /build/pathological/source.c.

How to debug standard c library functions like printf?

I wanted to debug printf function, so when I step inside the printf function (gdb debugger) it showed me this:
__printf (format=0x80484d0 " my name is Adam") at printf.c:28
28 printf.c: No such file or directory.
What is the meaning of this?
And when I again started step then there are a lot more statements like this.
Please help me to understand this.
I think it's pretty clear. There is a place where the gdb expects the source code to be, so download glibc's source code and put it there. I think the error message contains the full path.
If it's a linux distro it's fairly simple in fact because usually source packages are shipped too. Otherwise you need to find the source code yourself, note that it MUST be exactly the same that was used to compile the c library components, not just the same version because distributors often make changes to the sources.
Well, for the debugger to show you the code that was compiled into the binaries you're using, you need the original code somewhere.
You don't seem to have that, so your debugger can't find it.
Notice that you usually do not want to debug the source code of your std library functions, but only the way they are being called. For that, the usual "debug symbol" packages of your operating systems are optimal.
As others have answered, GDB was unable to find the source file.
For the C runtime libraries, Linux distributions may provide a debuginfo RPM that you can install, which may allow GDB to view the files. For example:
$ yum search glibc-debuginfo
...
glibc-debuginfo.x86_64 : Debug information for package glibc
glibc-debuginfo-common.x86_64 : Debug information for package glibc
...
The glibc package and the glibc-debuginfo are a matched pair. There is no explicit dependency, but glibc-debuginfo package won't work unless it is matched with the same version of glibc.
If you have the sources unpacked somewhere, but not where GDB is expecting them to be, you can attempt to use either the directory or the set substitute-path command to let GDB know where the sources are.
The directory command tells GDB to prepend a prefix ahead of any source file path it is attempting to find. For example, if the source tree is actually located under the /tmp, you could use:
(gdb) directory /tmp
The set substitute-path command is used to tell GDB to replace a matching prefix in a source file path with a different path prefix. For example, if the compiled source file was in /build/path/source.c, but in debugging the source file is actually in /usr/home/alice/release-1.1/source.c, then you could use:
(gdb) set substitute-path /build/path /usr/home/alice/release-1.1
The command assumes that you are only specifying a complete path names, so it won't perform the substitution on /build/pathological/source.c.

CMakeLists.txt configuration - simple but stuck - library not been added to generated project

I was originally following this tutorial: http://www.opengl-tutorial.org/miscellaneous/building-your-own-c-application/
just after about half way down, from where it says "Adding a source file in a project"
I created from this my CMakeLists.txt file as so:
cmake_minimum_required (VERSION 2.6)
project (Cube_Project)
find_package(OpenGL REQUIRED)
add_executable(Cube
main.cpp
)
include_directories(
external/glfw-2.7.6/include/
external/glm-0.9.4.0/
external/glew-1.9.0/include/
.
)
set(ALL_LIBS
${OPENGL_LIBRARY}
GLFW_276
GLEW_190
)
target_link_libraries(Cube
${ALL_LIBS}
)
but when I generate the project, I get this error:
ld: library not found for -lGLFW_276
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any ideas?
I think maybe I'm not using the right names in the set(....) section? My three libs are in a folder called external, which is the top level of the project (i.e. CMakeLists is also here).
I put a zip of the project if anyone wants to take a look at the folder layout of output XCode project structure: http://heather.sh/OpenGL_Project.zip
Thanks,
The library is not in the linker's library search path.
The target_link_libraries command is is very straightforward: It simply passes on all of its arguments to the linker without bothering whether any of those libraries actually exist.
In your case, the GLFW_276 library is missing (and possibly the GLEW_190 as well, since the error occurs before that one is being processed). Make sure the library is actually installed on your system and its filename actually matches the name you use here (eg. libGLFW_276.so).
Once you verify that you have the required file, you need to make sure that the linker is able to find it. If the file is not located in one of the standard directories, use either link_directories to add its location to the search path, or find_library to obtain the full path to the library file, which can then be given to target_link_libraries.

Installing a new library in Linux, and accessing it from my C code

I am working on a project which requires me to download and use this. Inside the downloaded folder, when extracted I am presented with three things:
A folder called "include"
A folder called "src"
A file called "Makefile"
After some research, I found out that I have to navigate to the directory which contains these files, and just type in the command make.
It seemed to install the library in my system. So I tried a sample bit of code which should use the library:
csp_conn_t * conn;
csp_packet_t * packet;
csp_socket_t * socket = csp_socket(0);
csp_bind(socket, PORT_4);
csp_listen(socket, MAX_CONNS_IN_Q);
while(1) {
conn = csp_accept(socket, TIMEOUT_MAX);
packet = csp_read(conn, TIMEOUT_NONE);
printf(ā€œ%S\r\nā€, packet->data);
csp_buffer_free(packet);
csp_close(conn);
}
That's all that was given for the sample server end of the code. So I decided to add these to the top:
#include <csp.h>
#include <csp_buffer.h>
#include <csp_config.h>
#include <csp_endian.h>
#include <csp_interface.h>
#include <csp_platorm.h>
Thinking I was on the right track, I tried to compile the code with gcc, but I was given this error:
csptest_server.c:1: fatal error: csp.h: No such file or directory
compilation terminated.
I thought I may not have installed the library correctly after all, but to make sure, I found out I could check by running this command, and getting this result:
find /usr -iname csp.h
/usr/src/linux-headers-2.6.35-28-generic/include/config/snd/sb16/csp.h
/usr/src/linux-headers-2.6.35-22-generic/include/config/snd/sb16/csp.h
So it seems like the csp.h is installed, maybe I am referencing it incorrectly in the header include line? Any insight? Thanks a lot.
The make command is probably only building the library, but not installing it. You could try sudo make install. This is the "common" method, but I recommend you to check the library's documentation, if any.
The sudo command is only necessary if you have no permissions to write the system's include and library directories, which may be your case.
Another possibility (instead of installing the library) is telling GCC the location of the library's source code and generated binaries (by means of the -I and -L options of the gcc command.
That Makefile will not install anything, just translate the source into a binary format.
The csp.h in the Linux kernel has nothing to do with your project, it's just a naming collision, likely to happen with three letter names.
In your case, I would presume you need to add the include directory to the compilation flags for your server, like gcc -I/path/to/csp/include/csp csptest_server.c.
(Next, you'll run into linker errors because you'll also want to specify -L/path/to/csp -lcsp so that the linker can find the binary code to link to.)

Resources