CMakeLists unable to find newly installed HDF5? - linux

I'm working on a program that worked on another computer (1st one) and trying to get it to work on my new computer (3rd one). When I go to build and type ccmake .., I get this error:
CMake Error at build/share/cmake/hdf5/hdf5-targets.cmake:67 (message):
The imported target "hdf5" references the file
"/home/myname/Desktop/MyProject/build/lib/libhdf5.a"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
"/home/myname/Desktop/MyProject/build/share/cmake/hdf5/h
df5-targets.cmake"
but not all the files it references.
Call Stack (most recent call first):
build/share/cmake/hdf5/hdf5-config.cmake:70 (INCLUDE)
build/share/cmake/hdf5/FindHDF5.cmake:85 (INCLUDE)
src/Thing/CMakeLists.txt:66 (find_package)
Even when I then installed hdf5 using sudo apt-get, I got the same error
I had to delete that lib directory because it contained boost files that are outdated and caused a huge list of errors, possibly because of a conflict since I newly installed boost files in usr/lib and usr/include on this new computer. I got this program to work on a 2nd computer by simply deleting that lib directory
Is the way to resolve this to change the CMakeLists.txt so that it refers to the directory of the newly installed hdf5? The CMakeLists.txt looks like:
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT (Projectname)
# CMake Modules
SET(CMAKE_MODULE_PATH
${PROJECT_BINARY_DIR}/share/cmake/hdf5
${CMAKE_SOURCE_DIR}/CMake
${CMAKE_MODULE_PATH})
SET(ENV{HDF5_ROOT_DIR_HINT} ${PROJECT_BINARY_DIR})
# Build output
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
#other stuff I excluded to keep this brief
Also, even if I delete all the files in the lib directory at home/myname/Desktop/MyProject/build/lib except for libhdf5.a, I get a bunch of boost errors. Its a very long output and I think its because make creates new boost files in lib that were originally from home/myname/Desktop/MyProject/build/lib, instead of referring to the newly installed boost files in usr/lib and usr/include
In case it helps, line 66 of src/Thing/CMakeLists.txt looks likefind_package(HDF5 COMPONENTS C CXX)
I could also post the contents of hdf5-config.cmake and FindHDF5.cmake, if necessary
EDIT: dpkg -l | greap hdf5 gives
ii hdf5-helpers 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - Helper tools
ii hdf5-tools 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - Runtime tools
ii libhdf5-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - runtime files - serial version
ii libhdf5-cpp-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - C++ libraries
ii libhdf5-dev 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - development files - serial version
ii libhdf5-openmpi-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - runtime files - OpenMPI version
ii libhdf5-openmpi-dev 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - development files - OpenMPI version
ii libhdf5-serial-dev 1.8.15-patch1+docs-4 all transitional dummy package

A not so short introduction to linking of third-party libraries on Linux:
Generally you should decide 2 aspects.
The first one is about "system vs custom library"
you may link your application against a library installed from a system package (in Debian using apt-get). This is the preferred way to compile programs on Linux unless you have some reasons against (see below). Also usually this is the easiest way, 'cause all build tools are configured to find library components in certain "well-known" places.
Link against a custom build of a library. Use this method if you need some custom build options for a library, or need a specific version of library not available in repostitories and so on.
The second step is to choose between static and dynamic library.
Usually in Linux applications are linked against dynamically loaded libraries (.so). This reduces applications size, may decrease memory consumption and application loading time (because libraries for a given application are in memory already), and sometimes simplifies small updates like security fixes - one needs to update just a single library instead of all applications that use this vulnerable library
But there're drawbacks as well :) If you plan to distribute your application linked with dynamic libraries to other computers you need to make sure that the libraries of required versions are on a given target computer. Each library may in turn be linked with other libraries and so on. In the end you have to distribute a whole copy of an operating system, like e.g. Steam for Linux does: internally it carries a large part of Ubuntu. So sometimes it may be wiser to link against a static library and include everything needed rignt into your app.
Back to the practical questions. Since you've already installed system packages with libhdf5 development files (libhdf5-dev) I suggest you to go with the "system library" (p1.1).
In this case you should remove all other copies of the library from your build tree completely and use the following code chunk in your CMakeLists.txt:
find_package(HDF5 REQUIRED)
...
include_directories(${HDF5_INCLUDE_DIRS})
...
target_link_libraries(yourapp ${HDF5_LIBRARIES} <other required libs>)
if your application is a C++ app you may use ${HDF5_CXX_LIBRARIES} instead of ${HDF5_LIBRARIES}.
If you decided to link against a static library, then you need to define a special variable HDF5_USE_STATIC_LIBRARIES before calling find_package(HDF5...):
set(HDF5_USE_STATIC_LIBRARIES ON)
find_package(HDF5 REQUIRED)
...
If you still wish to use a custom build of the library then you should
"explain" to find_package where to look for library components. You may run make DESTDIR=/some/path install in the HDF5 build tree and then use that /some/path as the value of HDF5_ROOT environmental variable when running cmake in your application build tree:
HDF5_ROOT=/some/path cmake .
In this case CMake will try to locate HDF5 components in that directory. I would remove sytem package libhdf5-dev before this operation (just in case) using apt-get remove libhdf5-dev.
But again I believe that you should have good reasons not to use the system libhdf5 package.

Related

wxWidgets fails to build due to missing wxxml.lib

Apparently anything GUI-related in terms of components involves XML. I cannot go around actually configuring and building wxWidgets from source because of that. I'm new to wxWidgets.
My current setup is on Win10 with MSVC v141 (Visual Studio 2017) with the latest CMake version (currently 3.21).
Inside the config.cmake of the wxWidgets projects (using latest master branch) I see
wx_get_dependencies(EXTRALIBS_XML xml)
I am also calling CMake with -DwxUSE_XML=ON (among other parameters) but this still leads to:
the XML dependency is nowhere to be found
respectively it's not built
Linking then fails with the following error:
LINK : fatal error LNK1104: cannot open file 'wxxml.lib' [C:\Users\...\CMakeBuilds\ef5b5ada-ee42-7735-988a-ae37c735ccff\build\deps\build\wxwidgets\libs\qa\wxqa.vcxproj]
What library is actually wxWidgets using and how do I trigger it's retrieval and accordingly configuration and building? Since I am adding wxWidgets to my CMake project as an ExternalProject component, I would appreciated something in that line of thought. However any kind of information regarding this issue is more than welcome especially since it will shine light on how to configure other features (if I want them in the future) such as WebView.
The wxxml.lib issue is fixed now. While fixing it I also discovered a bug (of sort) in the build system of wxWidgets.
The reason why it failed to build this library in particular was actually quite simple but due to the lack of knowledge in the dependencies of wxWidgets. I thought that wxWidgets, given it depends on XML so much, has its own XML parser. Well, not really. The wxXML component actually uses and underlying 3rd party dependency called EXPAT, which - as you can see in my question - I have deactivated since it was giving me issues during the build (due to the still present problem of not being able to automatically retrieve dependencies).
What I did was to clone the libexpat repository, add it as an ExternalProject, set the variables for the libraries and include directory and pass them onto my wxWidgets project. But there is a catch...
The expat.cmake file looks as follows:
#############################################################################
# Name: build/cmake/lib/expat.cmake
# Purpose: Use external or internal expat lib
# Author: Tobias Taschner
# Created: 2016-09-21
# Copyright: (c) 2016 wxWidgets development team
# Licence: wxWindows licence
#############################################################################
if(wxUSE_EXPAT STREQUAL "builtin")
# TODO: implement building expat via its CMake file, using
# add_subdirectory or ExternalProject_Add
wx_add_builtin_library(wxexpat
src/expat/expat/lib/xmlparse.c
src/expat/expat/lib/xmlrole.c
src/expat/expat/lib/xmltok.c
)
set(EXPAT_LIBRARIES wxexpat)
set(EXPAT_INCLUDE_DIRS ${wxSOURCE_DIR}/src/expat/expat/lib)
elseif(wxUSE_EXPAT)
find_package(EXPAT REQUIRED)
endif()
I would use the *.cmake files of the 3rd party dependencies stored inside <ROOT_OF_WXWIDGETS_PROJECT>/build/cmake/lib to determine which variables I need to set if builtin is selected as the value for the respective library. Since I want to use my own I need sys (e.g. -DwxUSE_EXPAT=sys as a CMAKE_ARGS inside my wxWidgets ExternalProject) and also to pass the headers and libraries accordingly.
Given the file above one would assume that EXPAT_LIBRARIES is required. However after failing to build (yet again) and seeing that the reason was the activated expat build and that it was set as builtin I checked the log in detail and found the following error:
Could NOT find EXPAT (missing: EXPAT_LIBRARY) (found version "2.2.6")
Notice the EXPAT_LIBRARY. After passing it (-DEXPAT_LIBRARY=...) my build was complete. For me this is a bug or simply inconsistency between the dependency cmake file and the rest of the wxWidgets project.
It is important to note that I do not retrieve the external dependency through wxWidgets itself (see config.cmake and more precisely the macro wx_get_dependencies(...)). This solves the problem with a basic configuration and build of wxWidgets but if you don't want to tackle every dependency of wxWidgets on your own (why should you?), I recommend looking for a solution where the dependencies (at least the ones you don't want to deal with) are automatically retrieved, configured and build as builtin.

Is there a way to specify all the GDCM libraries in CMakeList at once?

This may be a very basic question, but I am unable to find the answer.
I just installed GDCM library on my Windows 7 workstation and compiled it with CMake and later built the generated solution using VS2012 Express.
However, I'm unsure about which GDCM libraries to include in the CMakeLists and I was wondering if there was an easier way to specify all the libraries at once.(like VTK_LIBRARIES for VTK). I tried GDCM_LIBRARIES and that doesn't return a value, neither does GDCM.
Specifically, I am looking to replace:
TARGET_LINK_LIBRARIES(TestvtkGDCMImageReader vtkgdcm gdcmMSFF gdcmDSED gdcm2vtk)
with something more general.
Typically, GDCM_LIBRARIES would be defined by the use file that you include after finding the GDCM package in CMake; however, it isn't currently set. You might just do it yourself by setting a variable with all of the GDCM library names.
For example, from looking at the libraries included in the 2.4.0 Windows binary distribution, I could do this in my CMakeLists.txt:
set( GDCM_LIBRARIES
gdcmDICT gdcmDSED gdcmIOD gdcmMEXD gdcmMSFF gdcmcharls gdcmexpat gdcmgetopt
gdcmjpeg12 gdcmjpeg16 gdcmjpeg8 gdcmopenjpeg gdcmzlib
# since you built the vtk component, you might also include them here
vtkgdcm gdcm2vtk
)
# then you can replace your line with this
target_link_libraries( TestvtkGDCMImageReader ${GDCM_LIBRARIES} )
Check out where the GDCM dlls you built are installed to see that you get all of the libraries.

How to link ".a" fat-static-libs with Apportable?

How do I link ".a" fat-static-libs with Apportable?
In the beginning, I did get a warning,
Warning: Library not found for lib-name. Try adding this to the
'deps' array in the 'add_params' section of your configuration.json
file. Check ~/.apportable/SDK/System for the directory names that
correspond to 'deps' entries.
I did add it to "deps" in the JSON right where it says this:
// A list of dependencies. Typically these correspond to frameworks in the xcode project.
My library isn't a framework, though. It's just a .a static library that has armv7, armv7s, and i386 parts which I assembled using lipo from two libraries (an armv7 and armv7s .a and a i386 .a) built with Xcode. They both use a single framework which is this Boost framework.
Adding it under deps squelched that warning message, but the apportable linker is still giving undefined references, so it is still not properly linking this file.
Now I know that Apportable has to re-jitter all this stuff, since Android won't know what to do with a Mac-executable format, so it's probably got to go pick apart my library and possibly turn it into an ELF-library before final linking. I'm not sure how to go about debugging this at this point, but is this supported at all?
Since you get "library not found" that means Apportable simply can't find the file. Hence the problem is merely with the file's location (or existence) and not what's in the library or how it is built.
The most common issue with dependent targets, especially Xcode projects dropped into other Xcode projects respectively workspaces with multiple projects, is that the resulting output of each target/project goes to different folders. Then Apportable (as well as xcodebuild under some circumstances) can't find the resulting libraries.
First step you should try is to make sure that the target dependencies are set. Select the app target, go to the Build Phases pane and under Target Dependencies add all frameworks and libraries that appear in the list and that your project depends on. This should ensure that the dependent frameworks/libraries do get built - because Xcode's built-in automatic dependency resolution isn't available to command line tools from what I understand. So you need to explicitly specify the dependent projects respectively their output.
If that doesn't help, you can force all targets to write their output to the same folder. Under Build Settings for every target change the Build Products Path (symbolic name: SYMROOT) to the same folder, for example ~/myprojectsbuildoutput
That way even dependent other projects will place their output in the same folder and xcodebuild as well as Apportable (it depends on xcodebuild) will be able to find the library files.
Tip: make sure your project builds successfully on the command line. Open Terminal, cd into the folder where the .xcodeproj bundle is and enter xcodebuild. If xcodebuild fails merely due to validation, disable Validate Built Product under Build Settings of the app target. If xcodebuild fails, Apportable likely isn't going to work either because it depends on xcodebuild. So as a prerequisite make sure that xcodebuild works on your project.
If xcodebuild also gives you "library not found" try calling it with a specific SYMROOT:
xcodebuild SYMROOT=~/myprojectsbuildoutput
If that then works you know you have to update each target's Build Projects Path. From what I know it's not currently possible (or not documented) to pass custom xcodebuild parameters via Apportable, so it needs to be set up in the .xcodeproj itself.

Why doesn't libicudata.so get smaller when I remove items from the data library?

I'm trying to build a custom ICU with a minimal data set. I've tried to follow the instructions at Reducing the Size of ICU's Data: Conversion Tables, but many of the files referenced don't exist in the ICU 4.8.1 source distribution. Specifically, I cannot find any files that match ucm*.mk.
I've also tried creating reslocal.mk files as indicated in e.g. ICU's source/data/lang/resfiles.mk. That did not help either. My build is the typical:
$ ./configure --prefix=/some/dir
$ make
$ make install
Regardless of what I do, libicudata.so.48.1 is about 17M. It shouldn't matter, but I'm building on Ubuntu 11.04.
See the note at the top of that page: (see
Note that ICU for C by default comes with pre-built data. The source
data files are not included unless ICU is downloaded from the
source repository. Alternatively, the Data Customizer may be used to
customize the pre-built data.
Your ICU is reading the prebuilt package from icu/source/data/in/*.dat and ignoring the .mk files. We have had requests for the source data to be included as a downloadable .zip and so we plan to do this in the future.
If you have any suggestions for how our instructions can be made more clear, please file a bug. I've added a copy of that notice to the section you referenced.

Linking with a different .so file in linux

I'm trying to compile a piece of software which has the standard build process e.g.
configure
make
make install
The software requires a library e.g. libreq.so which is installed in /usr/local/lib. However, my problem is I'd like to build the software and link it with a different version of the same library (i have the source for the library as well) that I've installed in /home/user/mylibs.
My question is, how do I compile and link the software against the library in /home/user/mylibs rather than the one in /usr/local/lib
I tried setting "LD_LIBRARY_PATH" to include /home/user/mylibs but that didn't work.
Thanks!
When you have an autoconf configure script, use:
CPPFLAGS=-I/home/user/include LDFLAGS=-L/home/user/mylibs ./configure ...
This adds the nominated directory to the list of directories searched for headers (usually necessary when you're using a library), and adds the other nominated directory to the list searched for actual libraries.
I use this all the time - on my work machine, /usr/local is 'maintained' by MIS and contains obsolete code 99.9% of the time (and is NFS-mounted, read-only), so I struggle to avoid using it at all and maintain my own, more nearly current, versions of the software under /usr/gnu. It works for me.
Try using LD_PRELOAD set to your actual file.
LD_LIBRARY_PATH is for finding the dynamic link libraries at runtime. At compiling you should add -L parameters to gcc/g++ to specify in which directory the *.so files are. You also need to add the library name with -l<NAME> (where the library is libNAME.so).
Important! For linking you not only need the libNAME.so file but a libNAME.a is needed too.
When you run the application, don't forget to add the dir to the LD_LIBRARY_PATH.
When you added the /home/user/mylibs to the LD_LIBRARY_PATH did you add it to the front or end of the existing paths? The tokens are searched in-order so you will want yours to appear first in the list.
Also, many standard build environments that use configure will allow you to specify an exact library for each required piece. You will have to run ./configure --help but you should see something like --using-BLAH-lib=/path/to/your/library or similar.

Resources