I am trying to include two libraries into my project to use them. I'm using CMake with CLion.
The two libraries are: https://github.com/herumi/bls and https://github.com/herumi/mcl
I got the following project setup:
This is the main CMake file:
cmake_minimum_required(VERSION 3.17)
project(blsbenchmark)
set(CMAKE_CXX_STANDARD 14)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(SOURCE_FILES src/main.cpp)
add_executable(blsbenchmark ${SOURCE_FILES})
include(FindPkgConfig)
find_package(bls REQUIRED)
include_directories(${BLS_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${BLS_LIBRARY})
find_package(mcl REQUIRED)
include_directories(${MCL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${MCL_LIBRARY})
The Findbls.cmake
:
set(FIND_BLS_PATHS
/opt/bls)
find_path(BLS_INCLUDE_DIR bls.h
PATH_SUFFIXES include
PATHS ${FIND_BLS_PATHS})
find_library(BLS_LIBRARY
NAMES bls384_256
PATH_SUFFIXES lib
PATHS ${FIND_BLS_PATHS})
The Findmcl.cmake
:
set(FIND_MCL_PATHS
/opt/mcl)
find_path(MCL_INCLUDE_DIR bn_c384_256.h, bn.h
PATH_SUFFIXES include
PATHS ${FIND_MCL_PATHS})
find_library(MCL_LIBRARY
NAMES mclbn384_256
PATH_SUFFIXES lib
PATHS ${FIND_MCL_PATHS})
This setup allows me to include the files of the library very nicely in my project:
However, problems arise because, as you can see, I can link the library files directly in my main (bn.h and bls.h) without their prefixes (bls/bls.h or mcl/bn.h).
Thus, when trying to build this I get a:
fatal error: mcl/bn.h: No such file or directory
11 | #include <mcl/bn.h>
| ^~~~~~~~~~
because the library itself requires the prefix "mcl/bn.h" path.
Thus, the question is how I can include these two libraries (mcl and bls) into my project with the prefix in the path such that this also is compatible with the two libraries.
As discussed in the Q&A here, you have to provide a different path to the include_directories()
command. In your case, you can provide the parent directory to those found in your custom Find Modules.
For example, for the mcl
repository, the header is located here mcl/include/mcl/bn.h
. This is how you've defined the include directories now:
mcl/include/mcl/ bn.h
^ ^
include directory #include header
To achieve what you want, this is how you should split this up:
mcl/include/ mcl/bn.h
^ ^
include directory #include header
So, use the parent directory to the one actually containing the header file.
set(FIND_MCL_PATHS
/opt/mcl)
# Find the path containing the header.
find_path(MCL_HEADER_DIR bn_c384_256.h, bn.h
PATH_SUFFIXES include
PATHS ${FIND_MCL_PATHS})
# If path with header file was found, set MCL_INCLUDE_DIR to the parent directory.
if(MCL_HEADER_DIR)
# Grab the parent directory to MCL_HEADER_DIR.
get_filename_component(PARENT_DIR ${MCL_HEADER_DIR} DIRECTORY)
set(MCL_INCLUDE_DIR ${PARENT_DIR} CACHE PATH "MCL include directory" FORCE)
endif()
find_library(MCL_LIBRARY
NAMES mclbn384_256
PATH_SUFFIXES lib
PATHS ${FIND_MCL_PATHS})
Now, you should be able to compile using the following include in your code:
#include <mcl/bn.h>