Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,38 @@ jobs:
- name: Install dependencies
run: |
if test ${{ matrix.os }} = ubuntu-latest
then sudo apt-get install -y libgtest-dev libmemtailor-dev
else brew install autoconf automake libtool googletest \
then sudo apt-get install -y pkg-config libgtest-dev libmemtailor-dev
else brew install autoconf automake libtool pkgconf googletest \
Macaulay2/tap/memtailor
echo "CPPFLAGS=-I$(brew --prefix)/include" >> $GITHUB_ENV
echo "LDFLAGS= -L$(brew --prefix)/lib" >> $GITHUB_ENV
fi
- name: Install dependency metadata for macOS CMake consumers
if: matrix.build-system == 'cmake' && runner.os == 'macOS'
shell: bash
run: |
# Current Homebrew CMake bottles omit dependency package metadata.
# Released Autotools builds supply it without depending on another PR.
prefix="$RUNNER_TEMP/dependencies"
export CPPFLAGS="-I$prefix/include $CPPFLAGS"
export LDFLAGS="-L$prefix/lib $LDFLAGS"
export PKG_CONFIG_PATH="$prefix/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
for dependency in memtailor:1.4; do
name=${dependency%:*}
version=${dependency#*:}
curl -fsSL "https://github.com/Macaulay2/$name/archive/refs/tags/v$version.tar.gz" \
-o "$RUNNER_TEMP/$name.tar.gz"
tar -xzf "$RUNNER_TEMP/$name.tar.gz" -C "$RUNNER_TEMP"
(
cd "$RUNNER_TEMP/$name-$version"
./autogen.sh
./configure --prefix="$prefix" --enable-shared
make -j2
make install
)
done
echo "CMAKE_PREFIX_PATH=$prefix${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}" >> "$GITHUB_ENV"
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> "$GITHUB_ENV"
- name: Build and check
run: |
mkdir build-dir
Expand All @@ -38,3 +64,37 @@ jobs:
ninja
src/mathic-unit-tests
fi
- name: Test installed CMake packages
if: matrix.build-system == 'cmake'
shell: bash
env:
CMAKE_BUILD_PARALLEL_LEVEL: 2
run: |
for shared in ON OFF; do
for config in Release Debug; do
build="$RUNNER_TEMP/mathic-$shared-$config"
prefix="$build/install"
cmake -S . -B "$build" -GNinja \
-DCMAKE_BUILD_TYPE="$config" -DBUILD_SHARED_LIBS="$shared" \
-DCMAKE_INSTALL_PREFIX="$prefix"
cmake --build "$build" --target install
ctest --test-dir "$build" --output-on-failure
# Check pkg-config before moving its installation prefix.
pc=$(find "$prefix" -name mathic.pc -print -quit)
flags=$(PKG_CONFIG_PATH="$(dirname "$pc")${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" pkg-config --cflags mathic)
expect_debug=OFF
if test "$config" = Debug; then
expect_debug=ON
[[ "$flags" == *-DMATHIC_DEBUG* ]]
else
[[ "$flags" != *-DMATHIC_DEBUG* ]]
fi
mv "$prefix" "$build/relocated"
cmake -S cmake/tests -B "$build/consumer" -GNinja \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=11 \
-DCMAKE_PREFIX_PATH="$build/relocated" \
-DEXPECT_DEBUG="$expect_debug"
cmake --build "$build/consumer"
ctest --test-dir "$build/consumer" --output-on-failure
done
done
52 changes: 35 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.18)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(mathic VERSION 1.5 LANGUAGES CXX)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(CTest)

option(enable_pqsim "Build pqsim" OFF)
option(enable_divsim "Build divsim" OFF)

set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})

find_package(Threads 2.1 REQUIRED QUIET)
find_package(Memtailor REQUIRED)

add_library(memtailor STATIC IMPORTED)
set_target_properties(memtailor PROPERTIES
IMPORTED_LOCATION "${MEMTAILOR_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MEMTAILOR_INCLUDE_DIR}")
find_package(Threads REQUIRED QUIET)
find_package(Memtailor REQUIRED)
add_library(memtailor ALIAS memtailor::memtailor)

add_compile_options(
-DPACKAGE_NAME="${PROJECT_NAME}"
Expand All @@ -31,16 +31,34 @@ add_compile_options(

add_subdirectory(src)

set_target_properties(mathic PROPERTIES PUBLIC_HEADER src/mathic.h)
set_target_properties(mathic PROPERTIES
VERSION 0.0.5 SOVERSION 0 PUBLIC_HEADER src/mathic.h)
install(TARGETS mathic EXPORT mathicTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY src/mathic DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
install(FILES README.md lgpl-2.0.txt lgpl-2.1.txt lgpl-3.0.txt DESTINATION ${CMAKE_INSTALL_DOCDIR})

install(TARGETS mathic LIBRARY DESTINATION lib)
install(DIRECTORY src/mathic
DESTINATION include
FILES_MATCHING PATTERN "*.h"
)
install(FILES README.md lgpl-2.0.txt lgpl-2.1.txt lgpl-3.0.txt
DESTINATION licenses/mathic
)
set(mathic_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mathic")
configure_package_config_file(cmake/mathicConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/mathicConfig.cmake.in"
INSTALL_DESTINATION "${mathic_cmakedir}")
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicConfig.cmake"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/mathicConfig.cmake.in")
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/mathicConfigVersion.cmake"
VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion)
install(FILES cmake/FindMemtailor.cmake DESTINATION "${mathic_cmakedir}")
install(EXPORT mathicTargets NAMESPACE mathic:: DESTINATION "${mathic_cmakedir}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/mathicConfigVersion.cmake" DESTINATION "${mathic_cmakedir}")
configure_file(cmake/mathic.pc.in mathic.pc.in @ONLY)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathic.pc"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/mathic.pc.in")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathic.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

if(enable_pqsim)
add_executable(pqsim
Expand Down
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ check:
@echo "configured without gtest, so unittests cannot be run."

endif

EXTRA_DIST += cmake/mathicConfig.cmake.in \
cmake/tests/CMakeLists.txt cmake/tests/consumer.cpp
EXTRA_DIST += cmake/mathic.pc.in
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,39 @@ Copyright 2012 2013 Bjarke Hammersholt Roune (http://www.broune.com) and Michael
Mathic is licensed for use under the terms of GNU Lesser General Public License
version 2.0, and under any later version; the option is yours. See the files
lgpl-*.txt in this directory.

## Building and using the CMake package

This build requires CMake 3.18 or newer and a C++17 compiler.

```sh
cmake -S . -B build-dir -GNinja -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/your/install/prefix
cmake --build build-dir
ctest --test-dir build-dir --output-on-failure
cmake --install build-dir
```

`BUILD_TESTING=OFF` disables the GoogleTest dependency and unit tests.
Both shared and static installations provide headers, pkg-config metadata,
and a relocatable CMake package under the platform's library directory:

```cmake
find_package(mathic 1.5 CONFIG REQUIRED)
target_link_libraries(my_program PRIVATE mathic::mathic)
```

The target supplies C++17, include paths and transitive dependencies. Dependency
CMake configs are preferred; pkg-config metadata is supported for existing
system installations. Older Homebrew CMake bottles may lack both metadata
formats; build the dependency with its released Autotools build, or install a
CMake package that supplies the config. Bare header/library discovery is insufficient to propagate
dependencies' ABI flags. The dependency find modules are shipped with the config.
Use a quoted semicolon-separated `-DCMAKE_PREFIX_PATH='/prefix/one;/prefix/two'`
for nonstandard prefixes; the Unix environment variable uses colons instead.

The installed package exports `MATHIC_DEBUG` if the library was built in
Debug mode, even when the consumer uses Release. It inherits dependencies' own
ABI flags instead of forcing their Debug layouts. `pkg-config --cflags mathic`
also reports the installed library's Debug flag; pkg-config consumers should
select C++17 or later explicitly.
42 changes: 21 additions & 21 deletions cmake/FindMemtailor.cmake
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Try to find the MEMTAILOR libraries
# See https://github.com/Macaulay2/memtailor
#
# This file sets up GLPK for CMake. Once done this will define
# MEMTAILOR_FOUND - system has MEMTAILOR lib
# MEMTAILOR_INCLUDE_DIR - the MEMTAILOR include directory
# MEMTAILOR_LIBRARIES - Libraries needed to use MEMTAILOR
#
# Prefer the upstream config; pkg-config also carries the dependency's ABI flags.
# Copyright (c) 2020, Mahrud Sayrafi, <mahrud@umn.edu>
#
# Redistribution and use is allowed according to the terms of the BSD license.

find_path(MEMTAILOR_INCLUDE_DIR NAMES memtailor.h
PATHS ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/include
PATH_SUFFIXES memtailor
)
find_library(MEMTAILOR_LIBRARIES NAMES memtailor
PATHS ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/lib
)

if(NOT TARGET memtailor::memtailor)
find_package(memtailor CONFIG QUIET)
endif()
if(NOT TARGET memtailor::memtailor)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(MEMTAILOR QUIET IMPORTED_TARGET memtailor)
if(TARGET PkgConfig::MEMTAILOR)
add_library(memtailor::memtailor INTERFACE IMPORTED)
set_property(TARGET memtailor::memtailor PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::MEMTAILOR)
endif()
endif()
endif()
set(MEMTAILOR_FOUND FALSE)
if(TARGET memtailor::memtailor)
set(MEMTAILOR_FOUND TRUE)
set(MEMTAILOR_LIBRARIES memtailor::memtailor)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Memtailor DEFAULT_MSG MEMTAILOR_INCLUDE_DIR MEMTAILOR_LIBRARIES)

mark_as_advanced(MEMTAILOR_INCLUDE_DIR MEMTAILOR_LIBRARIES)
find_package_handle_standard_args(Memtailor DEFAULT_MSG MEMTAILOR_FOUND)
12 changes: 12 additions & 0 deletions cmake/mathic.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@

Name: mathic
Description: mathic library for Groebner basis computations
URL: https://github.com/Macaulay2/mathic
Version: @PROJECT_VERSION@
Requires: memtailor
Libs: -L${libdir} -lmathic
Libs.private: @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} $<$<CONFIG:Debug>:-DMATHIC_DEBUG>
14 changes: 14 additions & 0 deletions cmake/mathicConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
set(_mathic_module_path "${CMAKE_MODULE_PATH}")
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}")
find_dependency(Memtailor)
set(CMAKE_MODULE_PATH "${_mathic_module_path}")
include("${CMAKE_CURRENT_LIST_DIR}/mathicTargets.cmake")
# The ABI is determined by the installed library, not the consumer build type.
if($<CONFIG:Debug>)
set_property(TARGET mathic::mathic APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS MATHIC_DEBUG)
endif()
check_required_components(mathic)
10 changes: 10 additions & 0 deletions cmake/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.18)
project(mathic-consumer LANGUAGES CXX)
find_package(mathic 1.5 CONFIG REQUIRED)
add_executable(consumer consumer.cpp)
target_link_libraries(consumer PRIVATE mathic::mathic)
if(EXPECT_DEBUG)
target_compile_definitions(consumer PRIVATE EXPECT_DEBUG)
endif()
enable_testing()
add_test(NAME installed-consumer COMMAND consumer)
14 changes: 14 additions & 0 deletions cmake/tests/consumer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <mathic.h>
#include <memtailor.h>

#if defined(EXPECT_DEBUG) != defined(MATHIC_DEBUG)
#error Debug ABI must agree with the installed library
#endif
static_assert(__cplusplus >= 201703L, "C++17 must be inherited");

int main() {
memt::Arena arena;
void* p = arena.alloc(32);
arena.freeTop(p);
libmathicIsPresent();
}
11 changes: 6 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_compile_options(-DMATHIC_DEBUG -DMEMT_DEBUG)
endif()

add_library(mathic
mathic.h
mathic.cpp
Expand Down Expand Up @@ -35,11 +31,16 @@ add_library(mathic
mathic/stdinc.h
)

add_library(mathic::mathic ALIAS mathic)
target_compile_features(mathic PUBLIC cxx_std_17)
# Export the installed library's ABI; dependency targets supply their own flags.
target_compile_definitions(mathic PUBLIC $<BUILD_INTERFACE:$<$<CONFIG:Debug>:MATHIC_DEBUG>>)

target_link_libraries(mathic memtailor Threads::Threads)

target_include_directories(mathic PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

include(CTest)
Expand Down
Loading