From a9e6626c9b2e250eb9161c767d2fb2e5a07315e2 Mon Sep 17 00:00:00 2001 From: Francis Giraldeau Date: Wed, 8 Jul 2020 14:59:27 -0400 Subject: [PATCH] Export muparser cmake targets Export muparser targets, such that client projects can import it using find_package(). This mechanism for both the build tree and the install tree. The provided example3 shows how to import muparser targets. Signed-off-by: Francis Giraldeau Signed-off-by: Alexey Shvetsov --- CMakeLists.txt | 39 ++++++- CMakeLists.txt.orig | 173 ++++++++++++++++++++++++++++++++ muparserConfig.cmake.in | 6 ++ samples/example3/CMakeLists.txt | 12 +++ samples/example3/README.md | 2 + samples/example3/build.sh | 23 +++++ samples/example3/example3.cpp | 49 +++++++++ 7 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 CMakeLists.txt.orig create mode 100644 muparserConfig.cmake.in create mode 100644 samples/example3/CMakeLists.txt create mode 100644 samples/example3/README.md create mode 100755 samples/example3/build.sh create mode 100644 samples/example3/example3.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cfdce99..aecc67d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,11 @@ add_library(muparser src/muParserTest.cpp src/muParserTokenReader.cpp ) +# use the headers in the build-tree or the installed ones +target_include_directories(muparser PUBLIC + $ + $ +) # this compiles the "DLL" interface (C API) target_compile_definitions(muparser PRIVATE MUPARSER_DLL) @@ -77,9 +82,6 @@ set_target_properties(muparser PROPERTIES SOVERSION ${MUPARSER_VERSION_MAJOR} ) -# Install the export set for use with the install-tree -export(TARGETS muparser FILE "${CMAKE_BINARY_DIR}/muparser-targets.cmake") - if(ENABLE_SAMPLES) add_executable(example1 samples/example1/example1.cpp) target_link_libraries(example1 muparser) @@ -91,8 +93,10 @@ endif() # The GNUInstallDirs defines ${CMAKE_INSTALL_DATAROOTDIR} # See https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html include (GNUInstallDirs) +set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/muparser) install(TARGETS muparser + EXPORT muparser-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT RuntimeLibraries @@ -116,6 +120,35 @@ install(FILES COMPONENT Development ) +# Export the target under the build-tree (no need to install) +export(EXPORT muparser-export + FILE "${CMAKE_BINARY_DIR}/muparser-targets.cmake" + NAMESPACE muparser:: +) + +# Export the installed target (typically for packaging) +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/muparserConfigVersion.cmake" + VERSION ${MUPARSER_VERSION} + COMPATIBILITY AnyNewerVersion +) +configure_file(muparserConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/muparserConfig.cmake" + COPYONLY +) +install(EXPORT muparser-export + FILE muparser-targets.cmake + NAMESPACE muparser:: + DESTINATION ${INSTALL_CONFIGDIR} +) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/muparserConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/muparserConfigVersion.cmake + DESTINATION ${INSTALL_CONFIGDIR} + COMPONENT Development +) + # Define variables for the pkg-config file set(PACKAGE_NAME muparser) configure_file( diff --git a/CMakeLists.txt.orig b/CMakeLists.txt.orig new file mode 100644 index 0000000..b496584 --- /dev/null +++ b/CMakeLists.txt.orig @@ -0,0 +1,173 @@ +# CMake based on work from @xantares +cmake_minimum_required (VERSION 3.1.0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# By default, build in Release mode. Must appear before project() command +if (NOT DEFINED CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type") +endif () + +project(muParserProject) + + + +# Bump versions on release +set(MUPARSER_VERSION_MAJOR 2) +set(MUPARSER_VERSION_MINOR 3) +set(MUPARSER_VERSION_PATCH 2) +set(MUPARSER_VERSION ${MUPARSER_VERSION_MAJOR}.${MUPARSER_VERSION_MINOR}.${MUPARSER_VERSION_PATCH}) + +# Build options +option(ENABLE_SAMPLES "Build the samples" ON) +option(ENABLE_OPENMP "Enable OpenMP for multithreading" ON) +option(BUILD_SHARED_LIBS "Build shared/static libs" ON) + +if(ENABLE_OPENMP) + find_package(OpenMP REQUIRED) + set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") + set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +endif() + + +# Credit: https://stackoverflow.com/questions/2368811/how-to-set-warning-level-in-cmake/3818084 +if(MSVC) + # Force to always compile with W4 + if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif() +elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) + # Update if necessary + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") +endif() + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") +add_library(muparser + src/muParserBase.cpp + src/muParserBytecode.cpp + src/muParserCallback.cpp + src/muParser.cpp + src/muParserDLL.cpp + src/muParserError.cpp + src/muParserInt.cpp + src/muParserTest.cpp + src/muParserTokenReader.cpp +) +<<<<<<< HEAD +======= +# use the headers in the build-tree or the installed ones +target_include_directories(muparser PUBLIC + $ + $ +) +>>>>>>> e259981 (Export muparser cmake targets) + +# this compiles the "DLL" interface (C API) +target_compile_definitions(muparser PRIVATE MUPARSER_DLL) + +if (BUILD_SHARED_LIBS) + target_compile_definitions(muparser PRIVATE MUPARSERLIB_EXPORTS) +else () + target_compile_definitions(muparser PUBLIC MUPARSER_STATIC) +endif() + +if (CMAKE_BUILD_TYPE STREQUAL Debug) + target_compile_definitions(muparser PRIVATE _DEBUG) +endif () + +if(ENABLE_OPENMP) + target_compile_definitions(muparser PRIVATE MUP_USE_OPENMP) +endif() +set_target_properties(muparser PROPERTIES + VERSION ${MUPARSER_VERSION} + SOVERSION ${MUPARSER_VERSION_MAJOR} +) + +if(ENABLE_SAMPLES) + add_executable(example1 samples/example1/example1.cpp) + target_link_libraries(example1 muparser) + + add_executable(example2 samples/example2/example2.c) + target_link_libraries(example2 muparser) +endif() + +# The GNUInstallDirs defines ${CMAKE_INSTALL_DATAROOTDIR} +# See https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html +include (GNUInstallDirs) +set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/muparser) + +install(TARGETS muparser + EXPORT muparser-export + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT RuntimeLibraries +) + +install(FILES + include/muParserBase.h + include/muParserBytecode.h + include/muParserCallback.h + include/muParserDef.h + include/muParserDLL.h + include/muParserError.h + include/muParserFixes.h + include/muParser.h + include/muParserInt.h + include/muParserTemplateMagic.h + include/muParserTest.h + include/muParserToken.h + include/muParserTokenReader.h + DESTINATION include + COMPONENT Development +) + +# Export the target under the build-tree (no need to install) +export(EXPORT muparser-export + FILE "${CMAKE_BINARY_DIR}/muparser-targets.cmake" + NAMESPACE muparser:: +) + +# Export the installed target (typically for packaging) +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/muparserConfigVersion.cmake" + VERSION ${MUPARSER_VERSION} + COMPATIBILITY AnyNewerVersion +) +configure_file(muparserConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/muparserConfig.cmake" + COPYONLY +) +install(EXPORT muparser-export + FILE muparser-targets.cmake + NAMESPACE muparser:: + DESTINATION ${INSTALL_CONFIGDIR} +) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/muparserConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/muparserConfigVersion.cmake + DESTINATION ${INSTALL_CONFIGDIR} + COMPONENT Development +) + +# Define variables for the pkg-config file +set(PACKAGE_NAME muparser) +configure_file( + muparser.pc.in + ${CMAKE_BINARY_DIR}/muparser.pc + @ONLY +) +install( + FILES ${CMAKE_BINARY_DIR}/muparser.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig +) + +include(CTest) +enable_testing() + +add_executable (t_ParserTest test/t_ParserTest.cpp) +target_link_libraries(t_ParserTest muparser) +add_test (NAME ParserTest COMMAND t_ParserTest) + diff --git a/muparserConfig.cmake.in b/muparserConfig.cmake.in new file mode 100644 index 0000000..6a28a5e --- /dev/null +++ b/muparserConfig.cmake.in @@ -0,0 +1,6 @@ +get_filename_component(muparser_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +include(CMakeFindDependencyMacro) + +if(NOT TARGET muparser::muparser) + include("${muparser_CMAKE_DIR}/muparser-targets.cmake") +endif() diff --git a/samples/example3/CMakeLists.txt b/samples/example3/CMakeLists.txt new file mode 100644 index 0000000..0049c3e --- /dev/null +++ b/samples/example3/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.2) +project(muparser-example3) + +# find muparser target already installed +find_package(muparser 2.0 REQUIRED) + +add_executable(example3 example3.cpp) +target_link_libraries(example3 muparser::muparser) + +include(CTest) +add_test(example3 example3) + diff --git a/samples/example3/README.md b/samples/example3/README.md new file mode 100644 index 0000000..73e15d4 --- /dev/null +++ b/samples/example3/README.md @@ -0,0 +1,2 @@ +The example3 shows how to import and use muparser as an installed external +dependency using cmake `find_package()`. diff --git a/samples/example3/build.sh b/samples/example3/build.sh new file mode 100755 index 0000000..289fac9 --- /dev/null +++ b/samples/example3/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash -x + +CWD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +MP_SOURCES=${CWD}/../../ +MP_BUILD=${CWD}/muparser-build +MP_INSTALL=${CWD}/muparser-install +EX3_BUILD_TREE=${CWD}/example3-using-buildtree +EX3_INSTALL_TREE=${CWD}/example3-using-installtree + +# Build muparser and install it +cmake -H${MP_SOURCES} -B${MP_BUILD} -DCMAKE_INSTALL_PREFIX=${MP_INSTALL} +cmake --build ${MP_BUILD} --target install + +# Build the example using muparser build tree +cmake -H${CWD} -B${EX3_BUILD_TREE} -DCMAKE_PREFIX_PATH=${MP_BUILD} +cmake --build ${EX3_BUILD_TREE} --target all +cmake --build ${EX3_BUILD_TREE} --target test + +# Build the example using muparser install tree +cmake -H${CWD} -B${EX3_INSTALL_TREE} -DCMAKE_PREFIX_PATH=${MP_INSTALL} +cmake --build ${EX3_INSTALL_TREE} --target all +cmake --build ${EX3_INSTALL_TREE} --target test + diff --git a/samples/example3/example3.cpp b/samples/example3/example3.cpp new file mode 100644 index 0000000..78df86f --- /dev/null +++ b/samples/example3/example3.cpp @@ -0,0 +1,49 @@ +/* + + _____ __ _____________ _______ ______ ___________ + / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \ + | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/ + |__|_| /____/| __(____ /__| /____ >\___ >__| + \/ |__| \/ \/ \/ + Copyright (C) 2004 - 2020 Ingo Berg + + Redistribution and use in source and binary forms, with or without modification, are permitted + provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other materials provided + with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Small example using the cmake imported target. Include file and link library +// should work automagically. + +#include +#include + +int main() +{ + mu::Parser parser; + + mu::value_type values[] = { 1, 2 }; + parser.DefineVar("a", &values[0]); + parser.DefineVar("b", &values[1]); + + std::string expr = "a + b"; + parser.SetExpr("a + b"); + mu::value_type ans = parser.Eval(); + std::cout << expr << " == " << ans << "\n"; + + return (ans == 3.0) ? 0 : -1; +} -- 2.33.1