0

I am using the following cmake file:

cmake_minimum_required(VERSION 3.19)
project(Neon LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)

list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
include(libigl)

find_package(Boost REQUIRED COMPONENTS unit_test_framework)

add_executable(Neon src/main.cpp)

target_include_directories(${PROJECT_NAME} PUBLIC
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}}/include>
        $<INSTALL_INTERFACE:include>)

target_link_libraries(Neon PUBLIC Eigen3::Eigen igl::core igl::opengl_glfw solvers)

add_subdirectory(solvers)

I have my main executable, and I have my subdirectory "solvers" which has some other numerical routines. The CMake file for that is as follows:

project(solvers)

add_library(${PROJECT_NAME} SHARED src/LinearElastic.cpp)

target_include_directories(${PROJECT_NAME}
        PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src)

install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

target_link_libraries(${PROJECT_NAME} igl::core Eigen3::Eigen)

install(DIRECTORY include/ DESTINATION "${INSTALL_INCLUDE_DIR}")
install(EXPORT ${PROJECT_NAME}Config DESTINATION share/${PROJECT_NAME}/cmake)
export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}Config.cmake

Eigen and IGL are both libraries which are found from the following:

if(TARGET igl::core)
    return()
endif()

include(FetchContent)
FetchContent_Declare(
        libigl
        GIT_REPOSITORY https://github.com/libigl/libigl.git
        GIT_TAG v2.3.0
)

# Note: In libigl v3.0.0, the following will become a one-liner:
# FetchContent_MakeAvailable(libigl)

FetchContent_GetProperties(libigl)
if(NOT libigl_POPULATED)
    FetchContent_Populate(libigl)
endif()
list(PREPEND CMAKE_MODULE_PATH "${libigl_SOURCE_DIR}/cmake")
include(${libigl_SOURCE_DIR}/cmake/libigl.cmake)

Building the main executable has no issues whatsoever, however, when attempting to use the dependencies from the libigl library in the submodule, I am encountering a lot of problems where the imports are unable to resolve. In particular, when attempting to use Eigen, I get "Cannot open include file" errors.

I have tried googling this issue, but none seem to cover the case when I am using a custom-written include() for a library. Ordinarily I'd just find_package in the submodules, but this doesn't seem to work correctly. I assume this is something silly, or perhaps I'm misunderstanding. Please let me know if I can improve the clarity of the question.

The particular error is here:

#ifndef NEON_LINEARELASTIC_H
#define NEON_LINEARELASTIC_H

#include <Eigen/Dense> // "Cannot include" error

class LinearElastic {
public:
    Eigen::MatrixXi foobar;
    auto doIt() -> void;
};

#endif//NEON_LINEARELASTIC_
Jarred Parr
  • 1,167
  • 3
  • 11
  • 24
  • "I am encountering a lot of problems where ..." - Do not *describe* the errors. Instead, **show** (add it to the question post) your **code** which uses the library and **exact error message** it causes. – Tsyvarev Aug 21 '21 at 23:54
  • "Cannot open include file" errors. That IS the error. The import fails to resolve. I am looking to figure out how to get the include dirs to line up with submodules. – Jarred Parr Aug 22 '21 at 00:02
  • For clarity, I have amended my post with the exact code. – Jarred Parr Aug 22 '21 at 00:05

1 Answers1

0

I was able to solve this problem. I am typically used to a unix-based environment, so when attempting to apply the same typical thinking to windows, I encountered a few issues, namely, the way different compilers handle shared linking. To avoid rehashing what is already known, I defer to this post to allow anyone else encountering this issue to solve the problem.

I changed the CMakeLists.txt for my main executable to the following:

cmake_minimum_required(VERSION 3.19)
project(Neon LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(INSTALL_LIB_DIR lib CACHE PATH "Install directory for library code")
set(INSTALL_BIN_DIR CACHE PATH "Install directory for executables")
set(INSTALL_INCLUDE_DIR include CACHE PATH "Install directory for header files")

list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
include(libigl)

if(MSVC) // This line fixed it!
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
    set(BUILD_SHARED_LIBS TRUE)
endif()

foreach(p LIB BIN INCLUDE CMAKE)
    set(var INSTALL_${p}_DIR)
    if(NOT IS_ABSOLUTE "${${var}}")
        set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
    endif()
endforeach()

find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories("${PROJECT_SOURCE_DIR}"
        "${PROJECT_BINARY_DIR}")

add_executable(Neon src/main.cpp)

target_include_directories(${PROJECT_NAME} PUBLIC
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}}/include>
        $<INSTALL_INTERFACE:include>)

target_link_libraries(Neon PRIVATE Eigen3::Eigen igl::core igl::opengl_glfw solvers)

add_subdirectory(solvers)

By setting the windows-specific options, the app was able to build and run without issue.

Jarred Parr
  • 1,167
  • 3
  • 11
  • 24