Problems with the CMake files for CFITSIO

Not long ago I pulled down the CFITSIO repository and built it. The exact sequence of commands was:

#
# Download CFITSIO from <https://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio-4.5.0.tar.gz>
# to your Downloads folder, then untar it, build and install CFITSIO
#
cd ~/Downloads
wget https://github.com/HEASARC/cfitsio/archive/refs/tags/cfitsio4_5_0_20240826.tar.gz
tar -zxvf cfitsio4_5_0_20240826.tar.gz
cd cfitsio-cfitsio4_5_0_20240826
#
# Get the updated CMakeLists.txt
#
rm CMakeLists.txt
wget https://raw.githubusercontent.com/HEASARC/cfitsio/37f72c0ae47a17184bdadb83f83ef5ff1b184f69/CMakeLists.txt
mkdir build
cmake -B build -G Ninja -DBUILD_SHARED_LIBS=OFF -DUSE_PTHREADS=ON -DUSE_BZIP2=OFF
cd build
ninja
sudo ninja install

That worked well! Unfortunately when I added the following lines to the CMakeLists.txt file for my project:

set(cfitsio_DIR "/usr/local/lib/cfitsio-4.5.0/")
find_package(cfitsio 4.5.0 REQUIRED)

I received:

1> [CMake] CMake Error at /usr/local/lib/cfitsio-4.5.0/cfitsio-config.cmake:37 (include):
1> [CMake]   include could not find requested file:
1> [CMake] 
1> [CMake]     /cfitsio-targets.cmake

This is probably because there’s a problem with file cfitsio-config-cmake.in from which cfitsio-config.cmake is built.

I’ve reported this to the HEASARC folks, but right now they are struggling with this problem, saying:

I think that file was submitted by a user, so it may not be straightforward to get them to sort this out. So far my attempts to get your approach working aren’t succeeding.

They did say that this (to me rather odd) incantation works:

# Find the library using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(CFITSIO REQUIRED IMPORTED_TARGET cfitsio)

# Add the include directories and link libraries to the target
add_executable(fpack fpack.c fpackutil.c)
target_link_libraries(fpack PkgConfig::CFITSIO)

If anyone who’s much better at cmake than I has time to look at this issue I’d be most grateful, particularly if you can contribute a fix!

Many thanks, David

That is most probably because of this line in their cfitsio-config.cmake.in:

include("${CFITSIO_CMAKE_DIR}/cfitsio-targets.cmake")

This CFITSIO_CMAKE_DIR variable doesn’t seem to be actually initialized to any value, so it resolves to an empty string, resulting in that /cfitsio-targets.cmake path, which fails your configuration. Apparently, it should be initialized here, but this line is commented out, and I can’t say what was their plan with that.

Usually(?), that include() statement would use CMAKE_CURRENT_LIST_DIR, so in a regular(?) project that line would look like this:

include("${CMAKE_CURRENT_LIST_DIR}/cfitsio-targets.cmake")

And the workaround they suggested is to use pkg-config, which this project also provides a config for, and that one seemingly has no such problem (since it works).

I’m a bit confused tho’ as they already did:

include("${_prefix}/lib/cmake/cfitsio/cfitsio-targets.cmake")

a few lines earlier??
D.

So apparently that one didn’t find the targets file, or it did but there was a “wrong” set of targets provided there, so that later condition if(NOT TARGET ${LIB_NAME}::${LIB_NAME}) made it fallback to include("${CFITSIO_CMAKE_DIR}/cfitsio-targets.cmake"), where it finally failed for good.

In general, it is rarely (if ever) a good idea to rely on relative path constructs like ../.., so I would get rid of that entire block and just go with CMAKE_CURRENT_LIST_DIR.

The problem probably lies in the cfitsio-targets.cmake file.

The variable LIB_NAME has no value when executing /usr/local/lib/cfitsio-4.5.0/cfitsio-config.cmake so things are going to go wrong :frowning:

I added this:

if(NOT TARGET cfitsio::cfitsio)
    message(FATAL_ERROR "cfitsio::cfitsio is not a TARGET")
endif()

and that reported that cfitsio::cfitsio is not a TARGET

not setting the “cfitsio::cfitsio” TARGET

That is what I meant by the “wrong” set of targets.