Cmake finds hdf5 but tries to link against dll on windows - c++

I use find_package(HDF5 COMPONENTS CXX REQUIRED) in my CMAKE script to load the include directories and libraries of HDF5. Cmake tells me
Found HDF5: C:/Program Files/HDF_Group/HDF5/1.10.0/bin/hdf5_cpp.dll (found version "1.10.0") found components: CXX
And generates my visual studio solution.
I also use the library stored in ${HDF5_LIBRARIES} ${HDF5_CXX_LIBRARIES} for my target, but when I try to build it, I get a Linker Error LNK1107 saying that for file hdf5_cpp.dll:
invalid or corrupt file: cannot read at 0x380
which I think is due to the fact that visual studio is trying to directly link against the dll file instead of against the lib file which is in another folder, namely in:
C:\Program Files\HDF_Group\HDF5\1.10.0\lib
Question: Is this a bug in FindHDF or did I configure something wrong?

I have not used hdf5 on windows for some time, but I do recall there being a bug that causes it to link against the dll instead of the lib.
you should manually set (either via the command line cmake -D method, or via the cmake gui)
HDF5_hdf5_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5.lib
HDF5_hdf5_cpp_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5_cpp.lib
etc. - or just
HDF5_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5.lib
HDF5_cpp_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5_cpp.lib
depending on whether you have an older or newer version of FindHDF5 (they change the library var names in newer versions - check the ones used to make sure you get them right - I'm doing this from memory so might have made a mistake)
EDIT:
If the option of manaully specifying the libs is a problem, then there is the option of using FindPackage(HDF5 NO_MODULE) if your hdf5 library was compiled using cmake generated makefilesetc.
When using NO_MODULE, the find package scripts will bypass the findhdf5.cmake script and look for the HDF5Config.cmake or hdf5-config.cmake file that is placed in the relevant subdir of the hdf5 build/install folfer.
This is cross platform friendly and is supported by all newer hdf5 versions - provided they were built using cmake and not ./configure ...

Related

Visual Studio's CMake with vcpkg: Error gdal is not found

I have been trying to build a cmake c++ project. More specifically I am trying to use the gdal library in this project. In the CMakeLists.txt it says find_library(GDAL gdal) after doing some research i found, that visual studio can open cmake files by default as mention in this thread: https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=vs-2019.
Moreover, visual studio should also automatically include the gdal library once i have set it up with vcpkg correctly. I've already downloaded the x64-windows version of the library (vcpkg install gdal:x64-windows) in order to build for the right architecture and made it available via vcpkg integrate install on a user-wide scope.
After some trial and error, everything works fine now, the toolchain gets included accordingly and the library is found automatically, resulting in a configuration like that:
However, when trying to include the header files (or anything else; see code snippet), visual studio does not seem to link the library correctly as it will result in the error message: cannot open source file "gdal/gdal.h".
#include <gdal/ogrsf_frmts.h>
#include <gdal/gdal.h>
#include <gdal>
Where should I further investigate?
As others have said vcpkg integrate install and vcpkg.cmake don't work together the reason being:
set_target_properties(${name} PROPERTIES VS_USER_PROPS do_not_import_user.props)
set_target_properties(${name} PROPERTIES VS_GLOBAL_VcpkgEnabled false)
this deactivates the integration. The reason to deactivate the integration is so that you don't write an incomplete CMakeLists.txt (e.g. missing the include directory or not linking all required libraries).
As such replace find_library(GDAL gdal) with find_package(GDAL REQUIRED) and target_link_libraries against the target GDAL::GDAL (https://cmake.org/cmake/help/v3.17/module/FindGDAL.html)

Custom build cmake using standard library also for project with lower gcc version

I have a custom build cmake v3.10.0 which was compiled with a gcc_4.8.3. I am using this custom build cmake to compile a cmake project that must use gcc _4.1.2 because of legacy code.
Executing cmake promted me with an error because it needs to use the libstdc++-IFX.so.6 provided by gcc_4.8.3 which I fixed by adding the path to the correct library in my LD_LIBRARY_PATH before the path to the libraries provided by gcc_4.1.2.
Compiling my project and linking an executable (which is done by c++) results in the linker taking the gcc_4.8.3 stdlibs over the gcc_4.1.2 libs. Is there any way to tell cmake to not use the libraries it needs for himself for my cmake project preferably without touching LD_LIBRARY_PATH?
Edits:
#squareskittles comment: I did read and try everything this post suggest but without any changes. The libstdc++-IFX.so.6 is still taken from gcc_4.8.3

How to build debug dynamic libraries?

I am building the Poco libraries from source code using cmake, following the instructions from the official website, on OSX High Sierra.
From that I get a bunch of files representing the dynamic libraries with extension *.dylib for example libPocoJSON.23.dylib.
However an external application is looking (in the same path locations), apart from the files created with the build, for other files of the library with a similar name such as to the created ones (they are different only for a d appended to the first part of the name). One example of such file is:
libPocoJSONd.23.dylib
I have found that these files are created with the debug build (while the release build creates only the files without the d extension).
How to perform the build of the debug? Should I look for a flag to active in any of the cmake file or it is a complete different source code?
How to perform the build of the debug?
Use cmake -DCMAKE_BUILD_TYPE=Debug
See CMAKE_BUILD_TYPE for details.

lapack complains about libgcc_s_sjlj-1.dll

I am trying to write a program that uses armadillo in Visual Studio. I downloaded Prebuilt libraries for lapack and blas from http://icl.cs.utk.edu/lapack-for-windows/lapack/. I also downloaded MinGW and added C:/MinGW/bin to my System PATH. C:/MinGW/bin has libgfortran-3.dll and libgcc_s_dw2-1.dll which are what the lapack documentation states is needed. However, when I attempt to run my program I get a runtime error stating that the program can't run because libgcc_s_sjlj-1.dll is missing. This dll does not come with MinGW and I tried downloading multiple versions. How can I get rid of this error?
The MinGW-w64 project have something called "personal builds". One of them is "sjlj". The library is built using a gcc compiler from this personal build.
Assuming that it was used the current latest version (6.3.0) and win32 threads the you can find the toolchain binaries here. If not, you can check some other versions.
You can either extract the dll you need or extract it and add it to your system path.

Possible causes for Boost not being found by CMake in certain situations?

I build a C++ project depending on the Boost library using CMake (3.4.1). Host platform is Linux, targets are that host and cross-build Android NDK.
I'm only using Boost header files and I just downloaded/extracted the boost folder (and I don't have a /usr/include/boost directory).
In my CMakeLists.txt file I declare the dependency to Boost like this:
find_package(Boost 1.57 REQUIRED)
And I configure my build like this:
BOOST_ROOT=/path/to/boost cmake ../src
Which actually works as expected for my native build.
When I now configure a build exactly the same way (only specifying some more environment variables and a CMAKE_TOOLCHAIN_FILE) CMake gives me:
BOOST_ROOT=/path/to/boost JAVA_HOME=/bla/bla/bla \
ANDROID_NDK=/bla/bla/bla \
ANDROID_SDK=/bla/bla/bla \
ANT=/usr/bin/ant \
cmake ../src -DCMAKE_TOOLCHAIN_FILE=/bla/bla/android.toolchain.cmake
CMake Error at /usr/share/cmake/Modules/FindBoost.cmake:1247 (message):
Unable to find the requested Boost libraries.
Unable to find the Boost header files. Please set BOOST_ROOT to the root
directory containing Boost or BOOST_INCLUDEDIR to the directory containing
Boost's headers.
Call Stack (most recent call first):
CMakeLists.txt:4 (find_package)
So I believe I did almost the same to build for the Android target but the very same method that finds Boost for the host-build doesn't work here.
I tried to set Boost_DIR, BOOSTROOT and BOOST_INCLUDEDIR all with the same effect. Also I've deleted all content in the build directory before trying anything new.
What can be possible reasons for this behavior? I've already tried to print BOOST_ROOT directly in the FindBoost.cmake script like this:
message("BOOST_ROOT: $ENV{BOOST_ROOT}")
With the expected behavior (writing BOOST_ROOT: /path/to/boost).
Of course I can cheat now and just link the boost folder into the include folder of the cross compiler but that's not nice of course and I want to find out what's going on.
When cross-compiling, the toolchain file normally sets the variable CMAKE_FIND_ROOT_PATH. Combined with the CMAKE_FIND_ROOT_PATH_MODE_LIBRARY variable set to ONLY, CMAKE_FIND_ROOT_PATH variable is used as effective chroot for find_library calls, so only libraries under the given prefix(es) are searched.
Analogue variables exist to adjust the behavior for find_path (used for searching include paths) and find_program.
THe toolchain file you use actually sets CMAKE_FIND_ROOT_PATH at line 1521:
set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin"
"${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}"
"${ANDROID_SYSROOT}"
"${CMAKE_INSTALL_PREFIX}"
"${CMAKE_INSTALL_PREFIX}/share" )
and below sets CMAKE_FIND_ROOT_PATH_MODE_* variables to ONLY. So you need to have Boost installed under one of these directories, and give hints (like BOOST_ROOT) relative to it.
Note, that Boost should be built for the target platform (Android NDK in you case), not for the platform where you cross-compile (Linux).