How to use FIND_JNI on cmake - java-native-interface

I'm trying to write a build for my project where I'm trying to replace autobuild, and I need to proper use FIND_JNI.
I could make a simple build but it's not properly finding jni.h
And I need to find a proper way (without a hack) to define the Java include as this needs to be portable to other users.

The following code works for me. In your root CMakeLists.txt file add:
find_package(JNI)
if (JNI_FOUND)
message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")
endif()

That solution did not worked for me, I used:
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
and
echo $JAVA_HOME
must return a valid path.

Related

Better way to include a directory in CMakeLists.txt

For my current CMake-project, i'm in need for the numpy/ndarrayobject.h-library. At first the project didn't compile and complained about numpy/ndarrayobject.h not being found in the include-path.
So what i did was sudo find / -type f -name 'ndarrayobject.h' and it spit out:
/usr/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h
which i included in CMakeLists.txt:
include_directories(/usr/lib/python3.8/site-packages/numpy/core/include/)
So, there is no actual error here. The project compiles and works as i expected it to. However, i think there must be a smarter way to find the directory. I have seen CMake-projects use
find_package(PythonLibs 3 REQUIRED)
find_package(OpenCV REQUIRED)
or something along these lines. So my initial thought is to learn about such macros to include the numpy-directory a bit smarter.
What are those macros called? Where are they defined? Where can i learn about them? Does such a macro exist for the above mentioned directory?
Is this maybe the wrong approach and there is a cleaner way to find and include the above mentioned directory?
However, i think there must be a smarter way
Yes, you are right, and you are on the right track.
What are those macros called? Where are they defined? Where can i learn about them?
Those are called "find modules", and are usually located in (assuming Unix/Linux): /usr/local/share/cmake-<version>. You can learn about them in the official documentation: https://cmake.org/cmake/help/v3.14/manual/cmake-developer.7.html#find-modules
However: The ability to find NumPy seems to have been added in CMake 3.14: https://cmake.org/cmake/help/v3.14/module/FindPython3.html.
So, assuming you are using CMake 3.14 or later, this should do the trick:
find_package(Python3 REQUIRED COMPONENTS NumPy)
# Use PUBLIC or INTERFACE scope if you need to
# propagate the include folder to dependents
target_include_directories(<your target> PRIVATE ${Python3_NumPy_INCLUDE_DIRS})
Here we use FindPython3.cmake, which exports a whole heap of variables related to Python, including the one you need: Python3_NumPy_INCLUDE_DIRS.
Edit: As #Pedro correctly pointed out, you can also link to NumPy and get access to its include that way. This is actually preferable, since you may have to link to NumPy libraries anyway when building your application, and this saves you from having to issue two separate commands.
target_link_libraries(<your target> Python3::NumPy)
Now you can include said header: #include <numpy/ndarrayobject.h>
If you are unable to use CMake 3.14 or newer, you can consult the latest find modules to see how it's done and simply write your own module, or build the latest CMake from source (which is trivial).

How to configure DBus dependencies with CMake

I am new to CMake and DBus. I am following along the guide here and make a basic program compile and execute.
The first problem that I ran into was my program will not find
<dbus/dbus.h>
I got around that issue by adding some include directories to my CMakeList.txt.
Currently, my CMakeLists.txt looks like this:
...
include_directories(/usr/lib/)
include_directories(/usr/include/dbus-1.0/)
include_directories(/usr/lib/x86_64-linux-gnu/dbus-1.0/include)
include_directories(/usr/include/glib-2.0)
include_directories(/usr/lib/x86_64-linux-gnu/glib-2.0/include/)
set (LIBS
dbus-1
dbus-glib-1
)
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${LIBS} )
Now, my program is complaining about not being able to find dbus-arch-deps.h
/usr/include/dbus-1.0/dbus/dbus.h:29:33: fatal error: dbus/dbus-arch-deps.h: No such file or directory
#include <dbus/dbus-arch-deps.h>
I know that the solution for this is to use proper command line flags or pkg-config. As discussed here and numerous other posts.
However, I do not know how to configure CMakeLists.txt to have similar effect.
My guess would be to add something like find_package(dbus-1) to CMakeLists.txt. And if that is correct, I am going to have to write my own Finddbus-1.cmake. Does this sound correct? Or is there an easier way?
I will appreciate any pointers.
You may get an existing FindDBus.cmake script (e.g., this one), copy it into your project, and use as
find_package(DBus REQUIRED)
# Use results of find_package() call.
include_directories(${DBUS_INCLUDE_DIRS})
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${DBUS_LIBRARIES})
Alternatively, as you know pkgconfig can find DBus, you may use CMake module PkgConfig. Actually, FindDBus.cmake script, referenced above, uses PkgConfig module in its implementation. Possible usage could be:
find_package(PkgConfig REQUIRED) # Include functions provided by PkgConfig module.
pkg_check_modules(DBUS REQUIRED dbus-1) # This calls pkgconfig with appropriate arguments
# Use results of pkg_check_modules() call.
include_directories(${DBUS_INCLUDE_DIRS})
link_directories(${DBUS_LIBRARY_DIRS})
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${DBUS_LIBRARIES})
However, using link_directories is not recommended, it is better to use absolute paths to libraries in target_link_libraries() call. That is why it is better to combine pkg_check_modules with find_library, as it is done in the referenced Find script. That answer describes generic way for use result of pkgconfig in CMake.

How to check in cmake whether a given header file is available for C++ project

I am using cmake to manage compilation of my project and it is my first time to use cmake. This tool is very convenient, as there is plethora of scripts and functions which allows to check if all necessary libraries are installed on a given computer. Sometimes, however, these generic sripts does not cover some specific case or they are not available at all for a given library. My question is then as follows:
What is the right cmake-style way of veryfying whether a given header file (hpp or h) is available in the include path?
Justification:
Most straigforward way is probably to use CHECK_INCLUDE_FILE macros. For example, if I would like to use UnitTest++ library, I could write
CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()
Unfortunately If it is done this way, the variable HAVE_UNITTESTXX is stored in the cache. If I install the UnitTest++ library in my system, cmake will still complain about UnitTest++.h not being installed. I can remove cache manually, but standard find package functions does not require that. I can also upgrade the code like this
CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
UNSET(HAVE_UNITTESTXX CACHE)
message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()
This solution works, but it does not look nice. I would like to know a cmake way to do this task.
Best regards!
The answer you are looking for is already on the CMake Wiki. They clearly tell to remove the file CMakeCache.txt or the cache line that bothers you by hand.
Unfortunately, there is no cleaner way to do this. Yours is already as good as it could be. I think that CMake tries to be convenient when everything is alright, hence the cache, and tries to force you to delete and regenerate it when you fail.
On the other hand, you could write a CHECK_INCLUDE_FILE_CXX_ERROR macro (or any cleaner name) to wrap your fatal error message so that you don't have to repeat the same code every time:
macro(CHECK_INCLUDE_FILE_CXX_ERROR INCLUDE_FILE HAVE_FILE)
CHECK_INCLUDE_FILE_CXX(${INCLUDE_FILE} ${HAVE_FILE})
IF(NOT ${HAVE_FILE})
UNSET(HAVE_UNITTESTXX CACHE)
message( FATAL_ERROR "${INCLUDE_FILE} is not found" )
ENDIF()
endmacro()
And then use it like this:
CHECK_INCLUDE_FILE_CXX_ERROR("UnitTest++.h" HAVE_UNITTESTXX)

Making autoconf search for C++ libraries

I'm writing my first configure.ac and need to search for a C++ library.
I tried the following line, but when run the configure script, it finds nothing.
AC_SEARCH_LIBS([xmlpp::Document::get_root_node], [xml++-2.6])
Probably something is wrong with it. So, how can I make autoconf look for C++ libraries? I don't want to supply a global method (and don't think libxml++ has one either).
You might want to try AX_CXX_CHECK_LIB from the Autoconf macro archive. you should probably make sure that you either use AC_LANG([C++]) or surround the call with AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]).
This link is about finding a C-style signature function to the library so that it can be tested by autoconf or write your own test:
https://nerdland.net/2009/07/detecting-c-libraries-with-autotools/
Maybe worth to try, but I am getting an error with the AC_LANG_PROGRAM macro. The problem is put -llibname before the foo.cpp file. My compiler cares about the order of the -l and cpp file. The linker will not be able to find the function in the library.
Hope this helps. My suggestion would be to use CMake instead of Autoconf.
This CMakeLists.txt file should get you started:
cmake_minimum_required(VERSION 2.8)
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:FindLibXml2
find_package(libxml2 2.6 REQUIRED) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:find_package
include_directories(${LIBXML2_INCLUDE_DIR}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories
add_executable(myApp main.cpp other.cpp) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_executable
target_link_libraries(myApp ${LIBXML2_LIBRARIES}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries
To use the file, after adjusting for your project of course. Put it in your Source dir as CMakeLists.txt, then:
mkdir build
cd build
cmake .. # This is like autoconf and generates the make files
make
If it sounds intriguing check out the giant youtube vid on all the benefits: http://www.youtube.com/watch?v=8Ut9o4OdSC0
It's good to use CMake, CTest, CDash, and CPack together in a project.

How to use itkvtkglue to use ITK with VTK?

I wanted to make the example which combines ITK with VTK called IO/ImageFileReader from wiki examples.
I downloaded itkvtkglue, extracted to a folder, configured with cmake and built with visual studio 2010.
but i can't use it when i try to configure the example given. Even though cmake finds the ItkVtkGlue_DIR by itself, it gives the error that he couldn't include the necessary files. Fails to include(${ItkVtkGlue_USE_FILE})
Should I somehow change the folders CMake looks for my ItkVtkGlue header files? Is there other way to use ITK & VTK together?
the error and file content are given below.
CMake Error at CMakeLists.txt:6 (include):
include could not find load file:
C:/Users/Emre
CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 2.6)
project(ImageFileReader)
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
add_executable(ImageFileReader ImageFileReader.cxx)
target_link_libraries(ImageFileReader
ItkVtkGlue ${VTK_LIBRARIES} ${ITK_LIBRARIES})
Thank you all for your help.
This is almost certainly one of the very common problems:
If the path to your tools contains a [space] character in it, then you must protect the file path from being split apart by encapsulating it in quotations "".
To be safe, you should always place file paths in quotations just incase one of your future collaborators tries to build on a path that has spaces in it.
You may also want to review:
http://www.vtk.org/Wiki/ITK/Examples#ItkVtkGlue