I write a project which is composed of several libraries and Intel MKL library. I want to use CMake to compile my project and I have two CMakeLists.txt
as the following.
In the root directory,
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(MMNET LANGUAGES CXX)
# use the new policy to allow CMake to link target libraries from other directories
cmake_policy(SET CMP0079 NEW)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-o2 -msse -msse2 ${OpenMP_CXX_FLAGS}")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(MKL_ROOT "/opt/intel/compilers_and_libraries_2019.4.243/linux/mkl")
# In the future modification, I will wirte my own find_package module.
# Now we set this path manually.
set(GSL_LIBRARY_PATH /usr/lib/x86_64-linux-gnu/libgsl.a)
set(DL_LIBRARY_PATH /usr/lib/x86_64-linux-gnu/libdl.a)
set(MKL_LIBRARY_FLAGS "-Wl,--start-group ${MKL_ROOT}/lib/intel64/libmkl_intel_lp64.a")
set(MKL_LIBRARY_FLAGS "${MKL_LIBRARY_FLAGS} ${MKL_ROOT}/lib/intel64/libmkl_gnu_thread.a")
set(MKL_LIBRARY_FLAGS "${MKL_LIBRARY_FLAGS} ${MKL_ROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lgomp -lpthread -lm -ldl")
find_package(Boost 1.58.0 COMPONENTS program_options REQUIRED)
find_package(OpenMP REQUIRED)
add_subdirectory(src)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(MMNET ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
target_link_libraries(dataIO PUBLIC ${Boost_LIBRARIES})
target_link_libraries(Params PUBLIC dataIO)
target_link_libraries(GenoData PUBLIC GenotypeBasis)
target_link_libraries(AuxGenoData PUBLIC GenotypeBasis)
target_link_libraries(GeneticCorr PUBLIC NumericUtils GenoData AuxGenoData)
target_link_libraries(LMMCPU PUBLIC GenoData)
list(APPEND LINK_STATIC_LIBRARIES dataIO Params Timer GenoData MemoryUtils
LMMCPU NumericUtils GeneticCorr GenotypeBasis
AuxGenoData)
target_link_libraries(MMNET PUBLIC ${LINK_STATIC_LIBRARIES}
${GSL_LIBRARY_PATH}
${DL_LIBRARY_PATH}
${MKL_LIBRARY_FLAGS})
In the subdirectory,
add_library(dataIO STATIC IOUtils.h
IOUtils.cpp)
add_library(Timer STATIC Timer.h
Timer.cpp)
add_library(Params STATIC Parameters.h
Parameters.cpp)
add_library(MemoryUtils STATIC MemoryUtils.h
MemoryUtils.cpp)
add_library(LMMCPU STATIC LMMCPU.h
LMMCPU.cpp)
add_library(NumericUtils STATIC NumericUtils.h
NumericUtils.cpp)
add_library(GenoData STATIC GenoData.h
GenoData.cpp)
add_library(GeneticCorr STATIC GeneticCorr.h
GeneticCorr.cpp)
add_library(GenotypeBasis STATIC GenotypeBasis.h
GenotypeBasis.cpp)
add_library(AuxGenoData STATIC AuxGenoData.h
AuxGenoData.cpp)
MESSAGE(STATUS "Finish building libraries")
In terms of the CMakeLists.txt
file from the root directory, there are three lines to deal with the Intel MKL library. I am not sure if there is another beautiful way to solve this problem.
set(MKL_LIBRARY_FLAGS "-Wl,--start-group ${MKL_ROOT}/lib/intel64/libmkl_intel_lp64.a")
set(MKL_LIBRARY_FLAGS "${MKL_LIBRARY_FLAGS} ${MKL_ROOT}/lib/intel64/libmkl_gnu_thread.a")
set(MKL_LIBRARY_FLAGS "${MKL_LIBRARY_FLAGS} ${MKL_ROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lgomp -lpthread -lm -ldl")
What’s more, in my root CMakeLists.txt
file, I write several targe_link_libraries
command to deal with the dependence between libraries. Is there any other better ways to do? Thank you!