Fortran cmake with FFTW3 - cmake

I'm building CMake file for my Fortran project. But I couldn't get FFTW3 since there's no such thing like
find_package(FFTW, ...)
like for HDF5.
My code include the module with
include "fftw3.f"
What could I do to build a platform-independent CmakeList?

Of course CMake can find FFTW3. Below is a project, where I do exactly that. Also Just go through the output files and look for hints of how to fix your setup / provide environment parameters for FindFFTW3.cmake to do the job for you.
https://github.com/kvahed/codeare

Related

CMake: How do I add a function to an installed config?

I am creating a library which I am building and installing with CMake. In the CMakeLists.txt is install(TARGETS mylib ...) to install the library itself and install(EXPORT ...) to create a CMake config. The CMake config means that the library can be found with find_package() by applications wanting to use the library from their own CMakeLists.txt. So far, nothing surprising.
But in addition to that I have useful_fn.cmake that contains a useful CMake function that I want to make available to the applications' CMakeLists.txt. I can install it manually with install install(FILE useful_fn.cmake), but how will the applications know where to find it? Can it be referenced from the config?
Even better, could the CMake config include the installed version directly? So merely running find_package(mylib) provides access to this CMake function? I could do this if I wrote my whole mylib-config.cmake by hand, rather than than getting CMake to generate it like it currently does, but I would really rather not do that just so that I can add one line (include(.../usefulfn.cmake)).
It is misconception that CMake should generate XXXConfig.cmake script. As opposite, intended behavior that CMake generates every other script (names can be any):
XXXConfigTargets.cmake with install(EXPORT)
XXXConfigVersion.cmake with write_basic_package_version_file()
and these scripts are included in the XXXConfig.cmake script written by hands, where you may define additional things:
# File: XXXConfig.cmake
include(${CMAKE_CURRENT_LIST_DIR}/XXXConfigVersion.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/XXXConfigTargets.cmake)
# Here you may provide additional functions and other things.
function(my_func)
...
endfunction()
See more in the CMake packaging documentation.
To clarify further, there is a module that helps your configure valid and relocatable config file.
See macro configure_package_config_file provided by CMakePackageConfigHelpers module.
As mentioned by #Tsyvarev, the XXXConfig.cmake file should still be written by hand but configured with configure_package_config_file instead of configure_file.

Using cmake to compile a non-cmake project

I have a project that uses cmake to be configured and compiled, but this project depends on an external source tree that uses the traditional configure / make / make install procedure. Is it possible to tell cmake that, before compiling the main project, configure (with some specific parameters), make and make install on the external source tree should be called first?
Thanks
I had the exact same question when coming across this one.
(In my case, wanting to properly add libncurses and libcaca, which are both Autoconf based, as dependecies (and git submodules), to my CMake based project.)
So just to have an answer set to the question, based off of mike.did's comment ;
CMake's ExternalProject module definitely seems to be the proper solution.
(also see:)
Compile other external libraries (without CMakeLists.txt) with CMake
Cleanest way to depend on a make-based C library in my CMake C++ project

How to get CMake to build a Fortran program with MPI support?

I was trying to parallelize a Fortran program using MPI. I use CMake to do the build of my program. It was difficult to find support on getting CMake to create a working makefile for Fortran with MPI support on google, but from what I could gather, I added the following commands to my CMakeLists.txt script:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_DIRS})
link_directories(${MPI_FortranLIBRARY_DIRS})
This will locate MPI on my system and then set the variables found in the following three commands. In my linking line, I added the MPI libraries variable to the list of the other libraries that my program needed to build.
target_link_libraries(${exe_name} otherlibs ${MPI_FortranLIBRARY_DIRS})
Doing cmake and then make worked to build the program and the program ran; however, when I tried to add more to the source which required me to include the mpif.h include file, my compilation failed due to not being able to find this header file. I also could not use mpi because the compiler cannot find the mpi.mod file in the path.
I inserted "message" commands into my CMakeLists.txt file and printed out the values of the variables that I was using for including and linking. It turns out that the variables, MPI_Fortran_INCLUDE_DIRS and MPI_FortranLIBRARY_DIRS weren't set to anything. A check of the module that CMake is actually using to set these variables (FindMPI.cmake) showed these variables to be non-existent. I changed my CMakeLists.txt file to use the correct variables:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_PATH})
link_directories(${MPI_Fortran_LIBRARIES})
target_link_libraries(${exe_name} otherlibs ${MPI_Fortran_LIBRARIES})
Now when I execute make, the compiler could find both mpif.h as well as mpi.mod.
UPDATE:
I want to mention that this solution worked for cmake version 2.8.10.1. When I moved my CMakeLists.txt scripts to a different machine that has cmake version 2.8.4, I get the same error about mpi.mod missing during the link stage. I checked the FindMPI.cmake module and, sure enough, there are no variables that specify the language (i.e. there is no MPI_Fortran_LIBRARIES variable, just a MPI_LIBRARIES variable, and this variable is not getting set to the correct location of the mpi library on that system. So this solution will be dependent on cmake version.
Sounds like you are not using the mpi compiler. That is fine, but you have to add a lot of flags then. There is not really an mpi compiler but a wrapper that sets the flags to be able to use mpi. With cmake I was able to do this by defining the fortran compiler I was going to use BEFORE the call to cmake. It's not a nice solution since you loose portability, but it works. I'm trying to find a better solution and define inside cmake what compiler to use, but have not been able to do so. In other words, this works for me:
FC=mpif90 cmake ../.
make
I was having the same problem as you. Hope this solves the issue. If anybody finds how to define the fortran compiler INSIDE cmake please post it!
as you've already noticed, you misspelled the name of two variables, namely MPI_Fortran_LIBRARIES and MPI_Fortran_LIBRARIES
It is useful also to add:
cmake_minimum_required(VERSION 2.8.10)
at the very beginning of your CMake to be sure that these variables will be defined.

llvm's cmake integration

I'm currently building a compiler/interpreter in C/C++.
When I noticed LLVM I thought it would fit greatly to what I needed and so I'm trying to integrate LLVM in my existing build system (I use CMake).
I read this bout integration of LLVM in CMake. I copy and pasted the example CMakeLists.txt, changed the LLVM_ROOT to ~/.llvm/ (that's where I downloaded and build LLVM and clang) and it says it isn't a valid LLVM-install. Best result I could achieve was the error message "Can't find LLVMConfig" by changing LLVM_ROOT to ~/.llvm/llvm.
My ~/.llvm/ folder looks like this:
~/.llvm/llvm # this folder contains source files
~/.llvm/build # this folder contains object, executable and library files
I downloaded LLVM and clang via SVN. I did not build it with CMake.
Is it just me or is something wrong with the CMakeLists.txt?
This CMake documentation page got rotted, but setting up CMake for LLVM developing isn't different from any other project. If your headers/libs are installed into non-standard prefix, there is no way for CMake to guess it.
You need to set CMAKE_PREFIX_PATH to the LLVM installation prefix or CMAKE_MODULE_PATH to prefix/share/llvm/cmake to make it work.
And yes, use the second code snippet from documentation (under Alternativaly, you can utilize CMake’s find_package functionality. line).

Having trouble getting CMake to work with third party libraries

I'm trying to make a small game using both SFML and Box2D. I have the following directory structure:
/
src/
game/ # my code
thirdparty/ # other libraries' code
box2d/
sfml/
bin/
etc...
I'm trying to set it up so that I can run make and have box2d or sfml compile as well if they need, since I might make some changes to the libraries.
I've tried putting this in my CMkaeLists.txt:
find_package(Box2D)
find_package(sfml-window)
find_package(sfml-graphics)
find_package(sfml-system)
as well as other things, but I keep getting errors and I'm not sure how to get around them. for example:
CMake Error at CMakeLists.txt:20 (find_package):
Could not find module Findsfml-window.cmake or a configuration file for
package sfml-window.
Adjust CMAKE_MODULE_PATH to find Findsfml-window.cmake or set
sfml-window_DIR to the directory containing a CMake configuration file for
sfml-window. The file will have one of the following names:
sfml-windowConfig.cmake
sfml-window-config.cmake
But I can't find any of the files it lists there.
The find_pacakge command is for finding packages that are defined in for cmake as modules or configurations. There is probably not a cmake module or config defined for these libraries. So, if you want to use the find package command to find these libraries then you will need to create a cmake module that knows how to find them. Given your stated requirements I would not think that this is easiest way to do it.
If you are statically linking you libraries then set up a custom target to invoke make on each of the libraries. Add the include directories to your include path. Use find_library command to find the libraries.
If you intend to dynamically link your libraries then create a custom target to build and install your libraries and you should be good as long as you install them in one of the normal places.
Have a gander here:
http://www.itk.org/Wiki/CMake:How_To_Find_Libraries Writing find modules
Take a look at the "Writing find modules" section. Be sure to read the document all the way through.
If you want to make redistributable and portable cmake projects, I think this is the right direction for you to go.