cmake_minimum_required(VERSION 3.1) # https://github.com/libigl/libigl/issues/751 # http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160425/351643.html if(APPLE) if(NOT CMAKE_LIBTOOL) find_program(CMAKE_LIBTOOL NAMES libtool) endif() if(CMAKE_LIBTOOL) set(CMAKE_LIBTOOL ${CMAKE_LIBTOOL} CACHE PATH "libtool executable") message(STATUS "Found libtool - ${CMAKE_LIBTOOL}") get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) foreach(lang ${languages}) # Added -c set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_LIBTOOL} -c -static -o ") endforeach() endif() endif() ### Available options ### option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" OFF) option(LIBIGL_WITH_CGAL "Use CGAL" OFF) option(LIBIGL_WITH_COMISO "Use CoMiso" OFF) option(LIBIGL_WITH_CORK "Use Cork" OFF) option(LIBIGL_WITH_EMBREE "Use Embree" OFF) option(LIBIGL_WITH_MATLAB "Use Matlab" OFF) option(LIBIGL_WITH_MOSEK "Use MOSEK" OFF) option(LIBIGL_WITH_OPENGL "Use OpenGL" OFF) option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" OFF) option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" OFF) option(LIBIGL_WITH_PNG "Use PNG" OFF) option(LIBIGL_WITH_TETGEN "Use Tetgen" OFF) option(LIBIGL_WITH_TRIANGLE "Use Triangle" OFF) option(LIBIGL_WITH_PREDICATES "Use exact predicates" OFF) option(LIBIGL_WITH_XML "Use XML" OFF) option(LIBIGL_WITH_PYTHON "Use Python" OFF) option(LIBIGL_WITHOUT_COPYLEFT "Disable Copyleft libraries" OFF) option(LIBIGL_EXPORT_TARGETS "Export libigl CMake targets" OFF) ################################################################################ ### Configuration set(LIBIGL_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") set(LIBIGL_SOURCE_DIR "${LIBIGL_ROOT}/include") set(LIBIGL_EXTERNAL "${LIBIGL_ROOT}/external") # Dependencies are linked as INTERFACE targets unless libigl is compiled as a static library if(LIBIGL_USE_STATIC_LIBRARY) set(IGL_SCOPE PUBLIC) else() set(IGL_SCOPE INTERFACE) endif() # Download and update 3rdparty libraries list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) include(LibiglDownloadExternal) ################################################################################ ### IGL Common ################################################################################ add_library(igl_common INTERFACE) target_include_directories(igl_common SYSTEM INTERFACE $ $ ) # Export igl_common as igl::common set_property(TARGET igl_common PROPERTY EXPORT_NAME igl::common) if(LIBIGL_USE_STATIC_LIBRARY) target_compile_definitions(igl_common INTERFACE -DIGL_STATIC_LIBRARY) endif() # Transitive C++11 flags include(CXXFeatures) target_compile_features(igl_common INTERFACE ${CXX11_FEATURES}) # Other compilation flags if(MSVC) # Enable parallel compilation for Visual Studio target_compile_options(igl_common INTERFACE /MP /bigobj) target_compile_definitions(igl_common INTERFACE -DNOMINMAX) endif() ### Set compiler flags for building the tests on Windows with Visual Studio include(LibiglWindows) if(BUILD_SHARED_LIBS) # Generate position independent code set_target_properties(igl_common PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON) endif() if(UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") endif() # Eigen if(TARGET Eigen3::Eigen) # If an imported target already exists, use it target_link_libraries(igl_common INTERFACE Eigen3::Eigen) else() igl_download_eigen() target_include_directories(igl_common SYSTEM INTERFACE $ $ ) endif() # C++11 Thread library find_package(Threads REQUIRED) target_link_libraries(igl_common INTERFACE ${CMAKE_THREAD_LIBS_INIT}) ################################################################################ ## CGAL dependencies on Windows: GMP & MPFR function(igl_download_cgal_deps) if(WIN32) igl_download_project(gmp URL https://cgal.geometryfactory.com/CGAL/precompiled_libs/auxiliary/x64/GMP/5.0.1/gmp-all-CGAL-3.9.zip URL_MD5 508c1292319c832609329116a8234c9f ) igl_download_project(mpfr URL https://cgal.geometryfactory.com/CGAL/precompiled_libs/auxiliary/x64/MPFR/3.0.0/mpfr-all-CGAL-3.9.zip URL_MD5 48840454eef0ff18730050c05028734b ) set(ENV{GMP_DIR} "${LIBIGL_EXTERNAL}/gmp") set(ENV{MPFR_DIR} "${LIBIGL_EXTERNAL}/mpfr") endif() endfunction() ################################################################################ function(compile_igl_module module_dir) string(REPLACE "/" "_" module_name "${module_dir}") if(module_name STREQUAL "core") set(module_libname "igl") else() set(module_libname "igl_${module_name}") endif() if(LIBIGL_USE_STATIC_LIBRARY) file(GLOB SOURCES_IGL_${module_name} "${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp") if(NOT LIBIGL_WITHOUT_COPYLEFT) file(GLOB COPYLEFT_SOURCES_IGL_${module_name} "${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp") list(APPEND SOURCES_IGL_${module_name} ${COPYLEFT_SOURCES_IGL_${module_name}}) endif() add_library(${module_libname} STATIC ${SOURCES_IGL_${module_name}} ${ARGN}) if(MSVC) target_compile_options(${module_libname} PRIVATE /w) # disable all warnings (not ideal but...) else() #target_compile_options(${module_libname} PRIVATE -w) # disable all warnings (not ideal but...) endif() else() add_library(${module_libname} INTERFACE) endif() target_link_libraries(${module_libname} ${IGL_SCOPE} igl_common) if(NOT module_name STREQUAL "core") target_link_libraries(${module_libname} ${IGL_SCOPE} igl) endif() # Alias target because it looks nicer message(STATUS "Creating target: igl::${module_name} (${module_libname})") add_library(igl::${module_name} ALIAS ${module_libname}) # Export as igl::${module_name} set_property(TARGET ${module_libname} PROPERTY EXPORT_NAME igl::${module_name}) endfunction() ################################################################################ ### IGL Core ################################################################################ if(LIBIGL_USE_STATIC_LIBRARY) file(GLOB SOURCES_IGL "${LIBIGL_SOURCE_DIR}/igl/*.cpp" "${LIBIGL_SOURCE_DIR}/igl/copyleft/*.cpp") endif() compile_igl_module("core" ${SOURCES_IGL}) ################################################################################ ### Download the python part ### if(LIBIGL_WITH_PYTHON) igl_download_pybind11() endif() ################################################################################ ### Compile the CGAL part ### if(LIBIGL_WITH_CGAL) # Try to find the CGAL library # CGAL Core is needed for # `Exact_predicates_exact_constructions_kernel_with_sqrt` if(NOT TARGET CGAL::CGAL) set(CGAL_DIR "${LIBIGL_EXTERNAL}/cgal") igl_download_cgal() igl_download_cgal_deps() if(EXISTS ${LIBIGL_EXTERNAL}/boost) set(BOOST_ROOT "${LIBIGL_EXTERNAL}/boost") endif() if(LIBIGL_WITH_PYTHON) option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" OFF) else() option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" ON) endif() find_package(CGAL CONFIG COMPONENTS Core PATHS ${CGAL_DIR} NO_DEFAULT_PATH) endif() # If CGAL has been found, then build the libigl module if(TARGET CGAL::CGAL AND TARGET CGAL::CGAL_Core) compile_igl_module("cgal") target_link_libraries(igl_cgal ${IGL_SCOPE} CGAL::CGAL CGAL::CGAL_Core) else() set(LIBIGL_WITH_CGAL OFF CACHE BOOL "" FORCE) endif() endif() # Helper function for `igl_copy_cgal_dll()` function(igl_copy_imported_dll src_target dst_target) get_target_property(other_libs ${src_target} INTERFACE_LINK_LIBRARIES) set(locations) list(APPEND locations ${main_lib} ${other_libs}) foreach(location ${locations}) string(REGEX MATCH "^(.*)\\.[^.]*$" dummy ${location}) set(location "${CMAKE_MATCH_1}.dll") if(EXISTS "${location}" AND location MATCHES "^.*\\.dll$") add_custom_command(TARGET ${dst_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${location}" $) endif() endforeach() endfunction() # Convenient functions to copy CGAL dlls into a target (executable) destination folder (for Windows) function(igl_copy_cgal_dll target) if(WIN32 AND LIBIGL_WITH_CGAL) igl_copy_imported_dll(CGAL::CGAL ${target}) igl_copy_imported_dll(CGAL::CGAL_Core ${target}) endif() endfunction() ################################################################################ ### Compile the CoMISo part ### # NOTE: this cmakefile works only with the # comiso available here: https://github.com/libigl/CoMISo if(LIBIGL_WITH_COMISO) compile_igl_module("comiso") if(NOT TARGET CoMISo) igl_download_comiso() add_subdirectory("${LIBIGL_EXTERNAL}/CoMISo" CoMISo) endif() target_link_libraries(igl_comiso ${IGL_SCOPE} CoMISo) endif() ################################################################################ ### Compile the cork part ### if(LIBIGL_WITH_CORK) set(CORK_DIR "${LIBIGL_EXTERNAL}/cork") if(NOT TARGET cork) # call this "lib-cork" instead of "cork", otherwise cmake gets confused about # "cork" executable igl_download_cork() add_subdirectory("${CORK_DIR}" "lib-cork") endif() compile_igl_module("cork") target_include_directories(igl_cork ${IGL_SCOPE} cork) target_include_directories(igl_cork ${IGL_SCOPE} "${CORK_DIR}/src") target_link_libraries(igl_cork ${IGL_SCOPE} cork) endif() ################################################################################ ### Compile the embree part ### if(LIBIGL_WITH_EMBREE) set(EMBREE_DIR "${LIBIGL_EXTERNAL}/embree") set(EMBREE_TESTING_INTENSITY 0 CACHE STRING "" FORCE) set(EMBREE_ISPC_SUPPORT OFF CACHE BOOL " " FORCE) set(EMBREE_TASKING_SYSTEM "INTERNAL" CACHE BOOL " " FORCE) set(EMBREE_TUTORIALS OFF CACHE BOOL " " FORCE) set(EMBREE_MAX_ISA "SSE2" CACHE STRING " " FORCE) set(EMBREE_STATIC_LIB ON CACHE BOOL " " FORCE) if(MSVC) set(EMBREE_STATIC_RUNTIME ON CACHE BOOL " " FORCE) endif() if(NOT TARGET embree) # TODO: Should probably save/restore the CMAKE_CXX_FLAGS_*, since embree seems to be # overriding them on Windows. But well... it works for now. igl_download_embree() add_subdirectory("${EMBREE_DIR}" "embree") endif() compile_igl_module("embree") target_link_libraries(igl_embree ${IGL_SCOPE} embree) target_include_directories(igl_embree ${IGL_SCOPE} ${EMBREE_DIR}/include) target_compile_definitions(igl_embree ${IGL_SCOPE} -DEMBREE_STATIC_LIB) endif() ################################################################################ ### Compile the matlab part ### if(LIBIGL_WITH_MATLAB) find_package(Matlab REQUIRED COMPONENTS MEX_COMPILER MX_LIBRARY ENG_LIBRARY MAT_LIBRARY) compile_igl_module("matlab") target_link_libraries(igl_matlab ${IGL_SCOPE} ${Matlab_LIBRARIES}) target_include_directories(igl_matlab ${IGL_SCOPE} ${Matlab_INCLUDE_DIRS}) endif() ################################################################################ ### Compile the mosek part ### if(LIBIGL_WITH_MOSEK) find_package(MOSEK REQUIRED) compile_igl_module("mosek") target_link_libraries(igl_mosek ${IGL_SCOPE} ${MOSEK_LIBRARIES}) target_include_directories(igl_mosek ${IGL_SCOPE} ${MOSEK_INCLUDE_DIRS}) target_compile_definitions(igl_mosek ${IGL_SCOPE} -DLIBIGL_WITH_MOSEK) endif() ################################################################################ ### Compile the opengl part ### if(LIBIGL_WITH_OPENGL) # OpenGL module compile_igl_module("opengl") # OpenGL library if (NOT CMAKE_VERSION VERSION_LESS "3.11") cmake_policy(SET CMP0072 NEW) endif() find_package(OpenGL REQUIRED) if(TARGET OpenGL::GL) target_link_libraries(igl_opengl ${IGL_SCOPE} OpenGL::GL) else() target_link_libraries(igl_opengl ${IGL_SCOPE} ${OPENGL_gl_LIBRARY}) target_include_directories(igl_opengl SYSTEM ${IGL_SCOPE} ${OPENGL_INCLUDE_DIR}) endif() # glad module if(NOT TARGET glad) igl_download_glad() add_subdirectory(${LIBIGL_EXTERNAL}/glad glad) endif() target_link_libraries(igl_opengl ${IGL_SCOPE} glad) endif() ################################################################################ ### Compile the GLFW part ### if(LIBIGL_WITH_OPENGL_GLFW) if(TARGET igl::opengl) # GLFW module compile_igl_module("opengl/glfw") if(NOT TARGET glfw) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL " " FORCE) set(GLFW_BUILD_TESTS OFF CACHE BOOL " " FORCE) set(GLFW_BUILD_DOCS OFF CACHE BOOL " " FORCE) set(GLFW_INSTALL OFF CACHE BOOL " " FORCE) igl_download_glfw() add_subdirectory(${LIBIGL_EXTERNAL}/glfw glfw) endif() target_link_libraries(igl_opengl_glfw ${IGL_SCOPE} igl_opengl glfw) endif() endif() ################################################################################ ### Compile the ImGui part ### if(LIBIGL_WITH_OPENGL_GLFW_IMGUI) if(TARGET igl::opengl_glfw) # ImGui module compile_igl_module("opengl/glfw/imgui") if(NOT TARGET imgui) igl_download_imgui() add_subdirectory(${LIBIGL_EXTERNAL}/libigl-imgui imgui) endif() target_link_libraries(igl_opengl_glfw_imgui ${IGL_SCOPE} igl_opengl_glfw imgui) endif() endif() ################################################################################ ### Compile the png part ### if(LIBIGL_WITH_PNG) # png/ module is anomalous because it also depends on opengl it really should # be moved into the opengl/ directory and namespace ... if(TARGET igl_opengl) if(NOT TARGET stb_image) igl_download_stb() add_subdirectory(${LIBIGL_EXTERNAL}/stb stb_image) endif() compile_igl_module("png" "") target_link_libraries(igl_png ${IGL_SCOPE} igl_stb_image igl_opengl) endif() endif() ################################################################################ ### Compile the tetgen part ### if(LIBIGL_WITH_TETGEN) set(TETGEN_DIR "${LIBIGL_EXTERNAL}/tetgen") if(NOT TARGET tetgen) igl_download_tetgen() add_subdirectory("${TETGEN_DIR}" "tetgen") endif() compile_igl_module("tetgen") target_link_libraries(igl_tetgen ${IGL_SCOPE} tetgen) target_include_directories(igl_tetgen ${IGL_SCOPE} ${TETGEN_DIR}) endif() ################################################################################ ### Compile the triangle part ### if(LIBIGL_WITH_TRIANGLE) set(TRIANGLE_DIR "${LIBIGL_EXTERNAL}/triangle") if(NOT TARGET triangle) igl_download_triangle() add_subdirectory("${TRIANGLE_DIR}" "triangle") endif() compile_igl_module("triangle") target_link_libraries(igl_triangle ${IGL_SCOPE} triangle) target_include_directories(igl_triangle ${IGL_SCOPE} ${TRIANGLE_DIR}) endif() ################################################################################ ### Compile the predicates part ### if(LIBIGL_WITH_PREDICATES) set(PREDICATES_DIR "${LIBIGL_EXTERNAL}/predicates") if(NOT TARGET predicates) igl_download_predicates() add_subdirectory("${PREDICATES_DIR}" "predicates") endif() compile_igl_module("predicates") target_link_libraries(igl_predicates ${IGL_SCOPE} predicates) target_include_directories(igl_predicates ${IGL_SCOPE} ${PREDICATES_DIR}) target_compile_definitions(igl_predicates ${IGL_SCOPE} -DLIBIGL_WITH_PREDICATES) endif() ################################################################################ ### Compile the xml part ### if(LIBIGL_WITH_XML) set(TINYXML2_DIR "${LIBIGL_EXTERNAL}/tinyxml2") if(NOT TARGET tinyxml2) igl_download_tinyxml2() add_library(tinyxml2 STATIC ${TINYXML2_DIR}/tinyxml2.cpp ${TINYXML2_DIR}/tinyxml2.h) target_include_directories(tinyxml2 PUBLIC ${TINYXML2_DIR}) set_target_properties(tinyxml2 PROPERTIES COMPILE_DEFINITIONS "TINYXML2_EXPORT" VERSION "3.0.0" SOVERSION "3") endif() compile_igl_module("xml") target_link_libraries(igl_xml ${IGL_SCOPE} tinyxml2) target_include_directories(igl_xml ${IGL_SCOPE} ${TINYXML2_DIR}) endif() ################################################################################ ### Install and export all modules if(NOT LIBIGL_EXPORT_TARGETS) return() endif() function(install_dir_files dir_name) if (dir_name STREQUAL "core") set(subpath "") else() set(subpath "/${dir_name}") endif() file(GLOB public_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.h ) set(files_to_install ${public_headers}) if(NOT LIBIGL_USE_STATIC_LIBRARY) file(GLOB public_sources ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.c ) endif() list(APPEND files_to_install ${public_sources}) install( FILES ${files_to_install} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igl${subpath} ) endfunction() ################################################################################ include(GNUInstallDirs) include(CMakePackageConfigHelpers) # Install and export core library install( TARGETS igl igl_common EXPORT igl-export PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) export( TARGETS igl igl_common FILE libigl-export.cmake ) # Install headers for core library install_dir_files(core) install_dir_files(copyleft) # Write package configuration file configure_package_config_file( ${CMAKE_CURRENT_LIST_DIR}/libigl-config.cmake.in ${CMAKE_BINARY_DIR}/libigl-config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/libigl/cmake ) install( FILES ${CMAKE_BINARY_DIR}/libigl-config.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/libigl/cmake ) # Write export file export(EXPORT igl-export FILE "${CMAKE_BINARY_DIR}/libigl-export.cmake" ) install(EXPORT igl-export DESTINATION ${CMAKE_INSTALL_DATADIR}/libigl/cmake FILE libigl-export.cmake) export(PACKAGE libigl)