diff --git a/CMakeLists.txt b/CMakeLists.txt index de1ffe9d..12e814d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,15 @@ option(MATPLOTPP_BUILD_HIGH_RESOLUTION_WORLD_MAP "Compile the high resolution ma option(MATPLOTPP_BUILD_FOR_DOCUMENTATION_IMAGES "Bypass show() commands and save figures as .svg at destruction" OFF) option(MATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND "Compile target with the experimental OpenGL backend" OFF) +# Optional dependencies +option(MATPLOTPP_WITH_JPEG "Require building with JPEG support" OFF) +option(MATPLOTPP_WITH_TIFF "Require building with TIFF support" OFF) +option(MATPLOTPP_WITH_PNG "Require building with PNG support" OFF) +option(MATPLOTPP_WITH_LAPACK "Require building with LAPACK support" OFF) +option(MATPLOTPP_WITH_BLAS "Require building with BLAS support" OFF) +option(MATPLOTPP_WITH_FFTW "Require building with FFTW support" OFF) +option(MATPLOTPP_WITH_OpenCV "Require building with OpenCV support" OFF) + # Where to find dependencies option(MATPLOTPP_WITH_SYSTEM_CIMG "Use system-provided CImg.h instead of bundled" OFF) option(MATPLOTPP_WITH_SYSTEM_NODESOUP "Use system-provided nodesoup instead of bundled" OFF) diff --git a/Matplot++Config.cmake.in b/Matplot++Config.cmake.in index 4efbd94a..e0b25cbb 100644 --- a/Matplot++Config.cmake.in +++ b/Matplot++Config.cmake.in @@ -11,11 +11,24 @@ if (NOT CMAKE_CXX_COMPILER_ID STREQUAL MATPLOT_BUILT_CXX_COMPILER_ID) endif() # Find dependencies + if(NOT ${MATPLOT_BUILT_SHARED}) include(CMakeFindDependencyMacro) list(APPEND CMAKE_MODULE_PATH ${MATPLOT_CONFIG_INSTALL_DIR}) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") + + # optional dependencies + set(MATPLOT_OPTIONAL_DEPENDENCIES JPEG TIFF ZLIB PNG LAPACK BLAS FFTW3 OpenCV) + foreach(MATPLOT_OPTIONAL_DEPENDENCY ${MATPLOT_OPTIONAL_DEPENDENCIES}) + if (@MATPLOTPP_WITH_${MATPLOT_OPTIONAL_DEPENDENCY}@) + find_dependency(${MATPLOT_OPTIONAL_DEPENDENCY} REQUIRED) + else() + find_dependency(${MATPLOT_OPTIONAL_DEPENDENCY}) + endif() + endforeach() + find_dependency(Filesystem COMPONENTS Experimental Final) + # OpenGL backend if (@MATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND@) find_dependency(glad) diff --git a/source/3rd_party/CMakeLists.txt b/source/3rd_party/CMakeLists.txt index b5656e12..5b806ea1 100644 --- a/source/3rd_party/CMakeLists.txt +++ b/source/3rd_party/CMakeLists.txt @@ -1,3 +1,5 @@ +set(EXPORTED_TARGETS) + ####################################################### ### NodeSoup ### ####################################################### @@ -44,7 +46,9 @@ endif() if(MASTER_PROJECT AND NOT BUILD_SHARED_LIBS) install(TARGETS nodesoup EXPORT Matplot++Targets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/Matplot++) + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) endif() @@ -52,6 +56,7 @@ endif() ### CImg ### ####################################################### add_library(cimg INTERFACE) +list(APPEND EXPORTED_TARGETS cimg) if(WITH_SYSTEM_CIMG) find_path(CIMG_INCLUDE_DIR CImg.h REQUIRED) else() @@ -69,57 +74,115 @@ find_package(PkgConfig) # Lots of optional packages are not a good idea in general. # It makes the library much less "packagable" (https://youtu.be/sBP17HQAQjk) # and much more difficult to make sure it works on multiple OSs -find_package(JPEG) + +if(MATPLOTPP_WITH_JPEG) + find_package(JPEG REQUIRED) +else() + find_package(JPEG QUIET) +endif() if(JPEG_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_jpeg) target_link_libraries(cimg INTERFACE ${JPEG_LIBRARIES}) target_include_directories(cimg INTERFACE ${JPEG_INCLUDE_DIRS}) endif() -find_package(TIFF) +if(MATPLOTPP_WITH_TIFF) + find_package(TIFF REQUIRED) +else() + find_package(TIFF QUIET) +endif() if(TIFF_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_tiff) target_link_libraries(cimg INTERFACE ${TIFF_LIBRARIES}) target_include_directories(cimg INTERFACE ${TIFF_INCLUDE_DIRS}) endif() -find_package(ZLIB) -if(ZLIB_FOUND) - find_package(PNG) - if (PNG_FOUND) - target_compile_definitions(cimg INTERFACE cimg_use_zlib cimg_use_png) - target_include_directories(cimg INTERFACE ${ZLIB_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}) - target_link_libraries(cimg INTERFACE ${ZLIB_LIBRARIES} ${PNG_LIBRARIES}) - endif () +if(MATPLOTPP_WITH_PNG) + find_package(ZLIB REQUIRED) + find_package(libpng) + if(NOT libpng_FOUND) + find_package(PNG REQUIRED) + endif() +else() + find_package(ZLIB QUIET) + find_package(libpng QUIET) + if(NOT libpng_FOUND) + find_package(PNG QUIET) + endif() +endif() +if(ZLIB_FOUND AND (libpng_FOUND OR PNG_FOUND)) + target_compile_definitions(cimg INTERFACE cimg_use_zlib cimg_use_png) + if (TARGET ZLIB::ZLIB) + target_link_libraries(cimg INTERFACE ZLIB::ZLIB) + else() + target_include_directories(cimg INTERFACE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(cimg INTERFACE ${ZLIB_LIBRARIES}) + endif() + if (TARGET png) + target_link_libraries(cimg INTERFACE png) + else() + target_include_directories(cimg INTERFACE ${libpng_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}) + target_link_libraries(cimg INTERFACE ${libpng_LIBRARIES} ${PNG_LIBRARIES}) + endif() endif() -find_package(LAPACK) +if(MATPLOTPP_WITH_LAPACK) + find_package(LAPACK REQUIRED) +else() + find_package(LAPACK QUIET) +endif() if(LAPACK_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_lapack) target_link_libraries(cimg INTERFACE ${LAPACK_LIBRARIES}) target_include_directories(cimg INTERFACE ${LAPACK_INCLUDE_DIRS}) endif() -find_package(BLAS) +if(MATPLOTPP_WITH_BLAS) + find_package(BLAS REQUIRED) +else() + find_package(BLAS QUIET) +endif() if(BLAS_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_blas) target_link_libraries(cimg INTERFACE ${BLAS_LIBRARIES}) target_include_directories(cimg INTERFACE ${BLAS_INCLUDE_DIRS}) endif() -find_package(FFTW) -if(FFTW_FOUND) +if(MATPLOTPP_WITH_FFTW) + find_package(FFTW3) + if(NOT FFTW3_FOUND) + find_package(FFTW REQUIRED) + endif() +else() + find_package(FFTW3 QUIET) + if(NOT FFTW3_FOUND) + find_package(FFTW QUIET) + endif() +endif() +if(FFTW3_FOUND OR FFTW_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_fftw3) - target_link_libraries(cimg INTERFACE ${FFTW_LIBRARIES}) - target_include_directories(cimg INTERFACE ${FFTW_INCLUDE_DIRS}) + if (TARGET FFTW3::fftw3) + target_link_libraries(cimg INTERFACE FFTW3::fftw3) + else() + target_include_directories(cimg INTERFACE ${FFTW3_INCLUDE_DIRS} ${FFTW_INCLUDE_DIRS}) + target_link_libraries(cimg INTERFACE ${FFTW3_LIBRARIES} ${FFTW_LIBRARIES}) + endif() endif() if (CMAKE_MODULE_PATH) - find_package(OpenCV QUIET) + if(MATPLOTPP_WITH_OpenCV) + find_package(OpenCV REQUIRED) + else() + find_package(OpenCV QUIET) + endif() if (OpenCV_FOUND) target_compile_definitions(cimg INTERFACE cimg_use_opencv) - target_link_libraries(cimg INTERFACE ${OpenCV_LIBRARIES}) - target_include_directories(cimg INTERFACE ${OpenCV_INCLUDE_DIRS}) + if(TARGET opencv_core) + target_link_libraries(cimg INTERFACE opencv_core) + else() + target_include_directories(cimg INTERFACE ${OpenCV_INCLUDE_DIRS}) + target_link_libraries(cimg INTERFACE ${OpenCV_LIBRARIES}) + endif() endif() else() message("No CMAKE_MODULE_PATH path for OpenCV configured") @@ -151,6 +214,6 @@ endif() # Install (only necessary for static lib build) if(MASTER_PROJECT AND NOT BUILD_SHARED_LIBS) - install(TARGETS cimg + install(TARGETS ${EXPORTED_TARGETS} EXPORT Matplot++Targets) -endif() \ No newline at end of file +endif() diff --git a/source/matplot/CMakeLists.txt b/source/matplot/CMakeLists.txt index 0e4a9317..3e4850af 100644 --- a/source/matplot/CMakeLists.txt +++ b/source/matplot/CMakeLists.txt @@ -90,7 +90,7 @@ add_library(matplot freestanding/plot.h ) -set(TARGETS matplot) +set(EXPORTED_TARGETS matplot) # Target aliases add_library(Matplot++::matplot ALIAS matplot) @@ -214,6 +214,13 @@ if (MATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND) # The biggest con of the OpenGL backend is that it cannot open a window # in another thread. All it can do is get in the middle of the render # loop and draw the plot. + add_library(matplot_opengl + backend/opengl_embed.h + backend/opengl_embed.cpp + backend/opengl.h + backend/opengl.cpp + ) + find_package(OpenGL) # https://github.com/Dav1dde/glad @@ -226,13 +233,13 @@ if (MATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND) # find_package(GLAD REQUIRE) would suffice if it worked well FetchContent_Declare(glad GIT_REPOSITORY https://github.com/Dav1dde/glad.git GIT_TAG v0.1.36) FetchContent_MakeAvailable(glad) + list(APPEND EXPORTED_TARGETS glad) endif() - if(TARGET glad AND NOT TARGET glad::glad) - # Alias glad to glad::glad - add_library(glad::glad ALIAS glad) - list(APPEND TARGETS glad) - endif() - if(NOT TARGET glad::glad) + if(TARGET glad::glad) + target_link_libraries(matplot_opengl PUBLIC glad::glad) + elseif(TARGET glad) + target_link_libraries(matplot_opengl PUBLIC glad) + else() # FindGLAD does not usually create a target, so we create an interface target add_library(glad::glad INTERFACE) target_include_directories(glad::glad INTERFACE ${GLAD_INCLUDE_PATH}) @@ -248,15 +255,9 @@ if (MATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND) FetchContent_MakeAvailable(glfw3) endif() - add_library(matplot_opengl - backend/opengl_embed.h - backend/opengl_embed.cpp - backend/opengl.h - backend/opengl.cpp - ) - target_link_libraries(matplot_opengl PUBLIC matplot glad::glad glfw ${CMAKE_DL_LIBS}) + target_link_libraries(matplot_opengl PUBLIC matplot glfw ${CMAKE_DL_LIBS}) - list(APPEND TARGETS matplot_opengl) + list(APPEND EXPORTED_TARGETS matplot_opengl) endif() ####################################################### @@ -264,7 +265,7 @@ endif() ####################################################### if (MATPLOTPP_BUILD_INSTALLER) # Install targets - install(TARGETS ${TARGETS} + install(TARGETS ${EXPORTED_TARGETS} EXPORT Matplot++Targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}