Home > Mobile >  Add header-only library to executable in CMake
Add header-only library to executable in CMake

Time:11-08

I am trying to include the Windows GNU GSL headers-only library (downloaded from https://gnuwin32.sourceforge.net/packages/gsl.htm) to an example code in C but have lots of errors unfortunately.

Here is the structure of my repository:

folder/
      gsl/
          gsl_sf_bessel.h
          gsl_mode.h
          *.h # other header files
      main.cpp
      CMakeLists.txt

main.cpp is as such:

#include <stdio.h>
#include <gsl_sf_bessel.h>

int main (void)
{
  double x = 5.0;
  double y = gsl_sf_bessel_J0 (x);
  printf ("J0(%g) = %.18e\n", x, y);
  return 0;
}

and CMakeLists.txt:

cmake_minimum_required(VERSION 3.0.0)
project(demoproject VERSION 0.1.0)


add_executable(
    demoexecutable
    main.cpp
    )

target_include_directories(
    demoexecutable
    PUBLIC
    gsl/
    )

The error I get when compiling is main.cpp is:

fatal error: gsl/gsl_mode.h: No such file or directory
[build]    26 | #include <gsl/gsl_mode.h>

It looks like it managed to find gsl_sf_bessel.h from gsl/ but gsl_sf_bessel.h needs in its turn gsl_mode.h which the compiler cannot find. Any ideas on how to solve this issue?

I tried different combinations in CMakeLists.txt of functions such as add_library, include_directories, target_link_libraries but nothing worked unfortunately.

CodePudding user response:

Try adding ${CMAKE_CURRENT_SOURCE_DIR} as an include directory. That is the directory that contains gsl/gsl_mode.h. The gsl directory does not contain itself, so adding it as an include directory will not make that error go away.

CodePudding user response:

I've adopted the following practice in my CMake projects:

1) Project's folder structure.

Have an include/${PROJECT_NAME} subfolder (i.e., include subfolder and, within that, another subfolder named after the project's name). For example, in your case:

demoproject_or_whatever
|- include
|   \- demoproject
|      \- gsl
|         |- gsl_sf_bessel.h
|         \- gsl_mode.h
|- src
\- test

2) src/CMakeLists.txt.

Set an include_dir var at the top of the file, then use it when setting the executable's target_include_directories.

set(include_dir ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME})

add_executable(${PROJECT_NAME} ${app_sources})

target_include_directories(${PROJECT_NAME} PUBLIC
    "$<BUILD_INTERFACE:${include_dir}>"
    "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

3. Including header files from source files.

Use paths relative to include/${PROJECT_NAME}.

#include <gsl/gsl_sf_bessel.h>
  • Related