Skip to content
Open
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
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ indent_style = unset
[*.{in,seed}]
indent_style = tab
trim_trailing_whitespace = false

[cmake/*.cmake.in]
indent_style = space
49 changes: 47 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ jobs:
- name: Install dependencies
run: |
if test ${{ matrix.os }} = ubuntu-latest
then sudo apt-get install -y libgtest-dev libmemtailor-dev \
then sudo apt-get install -y pkg-config libgtest-dev libmemtailor-dev \
libmathic-dev libtbb-dev
else brew install autoconf automake libtool googletest \
else brew install autoconf automake libtool pkgconf googletest \
Macaulay2/tap/memtailor Macaulay2/tap/mathic tbb
echo "CPPFLAGS=-I$(brew --prefix)/include" >> $GITHUB_ENV
echo "LDFLAGS= -L$(brew --prefix)/lib" >> $GITHUB_ENV
echo "CMAKE_PREFIX_PATH=$(brew --prefix)" >> $GITHUB_ENV
fi
# Build in parallel. make reads MAKEFLAGS from the environment,
# so this reaches the sub-makes distcheck runs as well.
Expand Down Expand Up @@ -65,6 +66,50 @@ jobs:
working-directory: build-dir
run: make distcheck

- name: Test installed CMake packages
if: matrix.build-system == 'cmake'
shell: bash
env:
CMAKE_BUILD_PARALLEL_LEVEL: 2
BUILD_CONFIG: ${{ matrix.debug && 'Debug' || 'Release' }}
EXPECT_DEBUG: ${{ matrix.debug && 'ON' || 'OFF' }}
WITH_TBB: ${{ matrix.tbb && 'ON' || 'OFF' }}
EXPECT_NO_TBB: ${{ matrix.tbb && 'OFF' || 'ON' }}
run: |
for shared in ON OFF; do
build="$RUNNER_TEMP/mathicgb-$shared"
prefix="$build/install"
cmake -S . -B "$build" -GNinja \
-DCMAKE_BUILD_TYPE="$BUILD_CONFIG" -DBUILD_SHARED_LIBS="$shared" \
-DBUILD_TESTING=OFF -Dwith_tbb="$WITH_TBB" \
-DCMAKE_INSTALL_PREFIX="$prefix"
cmake --build "$build" --target install
if pkg-config --exists memtailor mathic &&
{ test "$WITH_TBB" = OFF || pkg-config --exists tbb; }; then
pc=$(find "$prefix" -name mathicgb.pc -print -quit)
flags=$(PKG_CONFIG_PATH="$(dirname "$pc")${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" pkg-config --cflags mathicgb)
if test "$EXPECT_DEBUG" = ON; then
[[ "$flags" == *-DMATHICGB_DEBUG* ]]
else
[[ "$flags" != *-DMATHICGB_DEBUG* ]]
fi
if test "$EXPECT_NO_TBB" = ON; then
[[ "$flags" == *-DMATHICGB_NO_TBB* ]]
else
[[ "$flags" != *-DMATHICGB_NO_TBB* ]]
fi
else
echo "Skipping pkg-config flags: dependency .pc files are unavailable"
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" -DEXPECT_NO_TBB="$EXPECT_NO_TBB"
cmake --build "$build/consumer"
ctest --test-dir "$build/consumer" --output-on-failure
done

ubsan:
name: undefined behaviour sanitizer
runs-on: ubuntu-latest
Expand Down
50 changes: 35 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.18)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR
"In-source CMake builds are not supported. Use cmake -S . -B build-dir instead.")
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -14,7 +19,7 @@ set_property(CACHE with_tbb PROPERTY STRINGS auto ON OFF)

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

find_package(Threads 2.1 REQUIRED QUIET)
find_package(Threads REQUIRED QUIET)
find_package(Memtailor REQUIRED)
find_package(Mathic REQUIRED)
# The auto case has to be tested first, as if(with_tbb) is true for "auto".
Expand All @@ -37,17 +42,12 @@ else()
endif()
message(STATUS "Multithreading with TBB: ${with_tbb}")

add_library(memtailor STATIC IMPORTED)
set_target_properties(memtailor PROPERTIES
IMPORTED_LOCATION "${MEMTAILOR_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MEMTAILOR_INCLUDE_DIR}")

add_library(mathic STATIC IMPORTED)
set_target_properties(mathic PROPERTIES
IMPORTED_LOCATION "${MATHIC_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MATHIC_INCLUDE_DIR}")
add_library(memtailor ALIAS memtailor::memtailor)
add_library(mathic ALIAS mathic::mathic)

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

add_subdirectory(src)

Expand All @@ -61,7 +61,11 @@ set_target_properties(mathicgb PROPERTIES
VERSION ${MATHICGB_SOVERSION}.${MATHICGB_SO_AGE}.${MATHICGB_SO_REVISION}
SOVERSION ${MATHICGB_SOVERSION})

install(TARGETS mathicgb LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS mathicgb EXPORT mathicgbTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY src/mathicgb
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h"
Expand All @@ -79,14 +83,30 @@ if(with_tbb)
else()
set(PC_CFLAGS "-DMATHICGB_NO_TBB")
endif()
configure_file(mathicgb.pc.in mathicgb.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mathicgb.pc
string(APPEND PC_CFLAGS " $<$<CONFIG:Debug>:-DMATHICGB_DEBUG>")
configure_file(mathicgb.pc.in mathicgb.pc.in @ONLY)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, this overwrites mathicgb.pc.in in in-tree builds, e.g:

dtorrance9@cos-4a14312:~/src/mathicgb/mathicgb$ cmake -B. -S. -GNinja
-- Multithreading with TBB: ON
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/dtorrance9/src/mathicgb/mathicgb
dtorrance9@cos-4a14312:~/src/mathicgb/mathicgb$ git diff
diff --git a/mathicgb.pc.in b/mathicgb.pc.in
index fc66ee4..493c16c 100644
--- a/mathicgb.pc.in
+++ b/mathicgb.pc.in
@@ -1,13 +1,13 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
 

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's an interesting side effect, oops...

but cmake really hates in-tree builds, so I don't even know how to get there.

file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicgb.pc"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/mathicgb.pc.in")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicgb.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
install(FILES README.md gpl-2.0.txt gpl-3.0.txt
DESTINATION licenses/mathicgb
DESTINATION ${CMAKE_INSTALL_DOCDIR}
)

set(mathicgb_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mathicgb")
configure_package_config_file(cmake/mathicgbConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/mathicgbConfig.cmake.in"
INSTALL_DESTINATION "${mathicgb_cmakedir}")
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicgbConfig.cmake"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/mathicgbConfig.cmake.in")
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/mathicgbConfigVersion.cmake"
VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion)
install(FILES cmake/FindMemtailor.cmake cmake/FindMathic.cmake cmake/FindTBB.cmake DESTINATION "${mathicgb_cmakedir}")
install(EXPORT mathicgbTargets NAMESPACE mathicgb:: DESTINATION "${mathicgb_cmakedir}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mathicgbConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/mathicgbConfigVersion.cmake" DESTINATION "${mathicgb_cmakedir}")

if(enable_mgb)
add_executable(mgb
src/cli/GBMain.cpp
Expand Down
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,6 @@ check:
@echo "configured without gtest, so unittests cannot be run."

endif

EXTRA_DIST += cmake/mathicgbConfig.cmake.in \
cmake/tests/CMakeLists.txt cmake/tests/consumer.cpp
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,42 @@ Copyright 2012 2013 Bjarke Hammersholt Roune (http://www.broune.com) and Michael
Mathicgb is licensed for use under the terms of GNU General Public License
version 2 and under any later version; the option is yours. See the files
gpl-*.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(mathicgb 1.4 CONFIG REQUIRED)
target_link_libraries(my_program PRIVATE mathicgb::mathicgb)
```

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 `MATHICGB_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 mathicgb`
also reports the installed library's Debug flag; pkg-config consumers should
select C++17 or later explicitly.

`with_tbb` retains its ON/OFF/auto behavior. Both metadata formats propagate
`MATHICGB_NO_TBB` for a build without TBB, or the TBB dependency when enabled.
58 changes: 37 additions & 21 deletions cmake/FindMathic.cmake
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
# Try to find the mathic libraries
# See https://github.com/Macaulay2/mathic
#
# This file sets up mathic for CMake. Once done this will define
# MATHIC_FOUND - system has MATHIC lib
# MATHIC_INCLUDE_DIR - the MATHIC include directory
# MATHIC_LIBRARIES - Libraries needed to use MATHIC
#
# 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(MATHIC_INCLUDE_DIR NAMES mathic.h
PATHS ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/include
PATH_SUFFIXES mathic
)
find_library(MATHIC_LIBRARIES NAMES mathic
PATHS ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/lib
)

if(NOT TARGET mathic::mathic)
find_package(mathic CONFIG QUIET)
endif()
if(NOT TARGET mathic::mathic)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(MATHIC QUIET IMPORTED_TARGET mathic)
if(TARGET PkgConfig::MATHIC)
add_library(mathic::mathic INTERFACE IMPORTED)
set_property(TARGET mathic::mathic PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::MATHIC)
endif()
endif()
endif()
# Older installations may provide only headers and a library.
if(NOT TARGET mathic::mathic)
find_path(MATHIC_INCLUDE_DIR NAMES mathic.h
PATHS ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/include
PATH_SUFFIXES mathic)
find_library(MATHIC_LIBRARY NAMES mathic
PATHS ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/lib)
if(MATHIC_INCLUDE_DIR AND MATHIC_LIBRARY)
add_library(mathic::mathic UNKNOWN IMPORTED)
set_target_properties(mathic::mathic PROPERTIES
IMPORTED_LOCATION "${MATHIC_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MATHIC_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES memtailor::memtailor)
endif()
mark_as_advanced(MATHIC_INCLUDE_DIR MATHIC_LIBRARY)
endif()
set(MATHIC_FOUND FALSE)
if(TARGET mathic::mathic)
set(MATHIC_FOUND TRUE)
set(MATHIC_LIBRARIES mathic::mathic)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Mathic DEFAULT_MSG MATHIC_INCLUDE_DIR MATHIC_LIBRARIES)

mark_as_advanced(MATHIC_INCLUDE_DIR MATHIC_LIBRARIES)
find_package_handle_standard_args(Mathic DEFAULT_MSG MATHIC_FOUND)
57 changes: 36 additions & 21 deletions cmake/FindMemtailor.cmake
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
# 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
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep these as a fallback. In particular, this would mean we could keep using the homebrew packages in CI instead of having to build them from source.

Same comment for mathic.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we maintain the Homebrew taps in question, we can just update them, then everything will be OK. Anyhow, you merged my mathic PR already...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyhow, fixed by afacdb8

please see Macaulay2/mathic#30 for the corresponding fix for mathic.


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()
# Older installations may provide only headers and a library.
if(NOT TARGET memtailor::memtailor)
find_path(MEMTAILOR_INCLUDE_DIR NAMES memtailor.h
PATHS ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/include
PATH_SUFFIXES memtailor)
find_library(MEMTAILOR_LIBRARY NAMES memtailor
PATHS ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/lib)
if(MEMTAILOR_INCLUDE_DIR AND MEMTAILOR_LIBRARY)
add_library(memtailor::memtailor UNKNOWN IMPORTED)
set_target_properties(memtailor::memtailor PROPERTIES
IMPORTED_LOCATION "${MEMTAILOR_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MEMTAILOR_INCLUDE_DIR}")
endif()
mark_as_advanced(MEMTAILOR_INCLUDE_DIR MEMTAILOR_LIBRARY)
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)
18 changes: 18 additions & 0 deletions cmake/mathicgbConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
set(_mathicgb_module_path "${CMAKE_MODULE_PATH}")
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}")
find_dependency(Memtailor)
find_dependency(Mathic)
if(@with_tbb@)
find_dependency(TBB)
endif()
set(CMAKE_MODULE_PATH "${_mathicgb_module_path}")
include("${CMAKE_CURRENT_LIST_DIR}/mathicgbTargets.cmake")
# The ABI is determined by the installed library, not the consumer build type.
if($<CONFIG:Debug>)
set_property(TARGET mathicgb::mathicgb APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS MATHICGB_DEBUG)
endif()
check_required_components(mathicgb)
13 changes: 13 additions & 0 deletions cmake/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.18)
project(mathicgb-consumer LANGUAGES CXX)
find_package(mathicgb 1.4 CONFIG REQUIRED)
add_executable(consumer consumer.cpp)
target_link_libraries(consumer PRIVATE mathicgb::mathicgb)
if(EXPECT_DEBUG)
target_compile_definitions(consumer PRIVATE EXPECT_DEBUG)
endif()
if(EXPECT_NO_TBB)
target_compile_definitions(consumer PRIVATE EXPECT_NO_TBB)
endif()
enable_testing()
add_test(NAME installed-consumer COMMAND consumer)
20 changes: 20 additions & 0 deletions cmake/tests/consumer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <mathicgb.h>
#include <mathic.h>
#include <memtailor.h>

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

int main() {
libmathicIsPresent();
memt::Arena arena;
void* p = arena.alloc(32);
arena.freeTop(p);
mgb::GroebnerConfiguration config(101, 2, 1);
return config.modulus() == 101 && config.varCount() == 2 ? 0 : 1;
}
Loading
Loading