Skip to content

Commit

Permalink
Merge libsingular-julia back into Singular.jl (#657)
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin authored Jun 7, 2023
2 parents 4753eda + 7f80d3d commit 14fdb93
Show file tree
Hide file tree
Showing 22 changed files with 3,827 additions and 0 deletions.
53 changes: 53 additions & 0 deletions deps/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
cmake_minimum_required(VERSION 3.01)

# I don't know why I need the following, but it works
if(POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif()

project(libsingular_julia)

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

find_package(JlCxx REQUIRED)

include(CheckCXXCompilerFlag)

set(CMAKE_CXX_STANDARD 14)

set(JLSINGULAR_TARGET singular_julia)

# avoid gcc 9 internal compiler error,
# see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90998
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.0
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.3)
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-conversion" )
endif()

# to avoid lib64 dirs as binarybuilder uses lib everywhere
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_INSTALL_LIBDIR "lib")

get_target_property(JlCxx_location JlCxx::cxxwrap_julia LOCATION)
get_filename_component(JlCxx_location ${JlCxx_location} DIRECTORY)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${JlCxx_location}")

message(STATUS "Found JlCxx at ${JlCxx_location}")

include_directories(${CMAKE_INSTALL_PREFIX})
include_directories(${Singular_PREFIX}/include/singular)

SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g ${extra_cppflags} -I${CMAKE_INSTALL_PREFIX}/include -I${Singular_PREFIX}/include/" )
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -v ${extra_ldflags} -L${CMAKE_INSTALL_PREFIX}/lib -Wl,-rpath,${CMAKE_INSTALL_PREFIX}/lib -L${Singular_PREFIX}/lib -Wl,-rpath,${Singular_PREFIX}/lib" )


add_library(${JLSINGULAR_TARGET} SHARED singular.cpp rings.cpp coeffs.cpp ideals.cpp matrices.cpp caller.cpp coeff_rings.cpp threading.cpp)

target_link_libraries(${JLSINGULAR_TARGET} JlCxx::cxxwrap_julia -lSingular -lpolys -lsingular_resources -lfactory -lomalloc -ldl -lgmp)

install(TARGETS
${JLSINGULAR_TARGET}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
674 changes: 674 additions & 0 deletions deps/src/LICENSE.md

Large diffs are not rendered by default.

82 changes: 82 additions & 0 deletions deps/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# libsingular-julia

This is the C++ library accompanying [Singular.jl](https://github.com/oscar-system/Singular.jl).
It implements the C++ interface from julia to Singular using [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl) and [libcxxwrap-julia](https://github.com/JuliaInterop/libcxxwrap-julia).

This library is compiled into a Julia artifact and shipped to the user via
the Julia JLL package
[libsingular_julia_jll](https://github.com/JuliaBinaryWrappers/libsingular_julia_jll.jl).
This JLL package in turn is generated from the sources in this repository and
the build recipe at
<https://github.com/JuliaPackaging/Yggdrasil/tree/master/L/libsingular_julia>.


## Quick way to test changes in here

To test changes you make to the C++ code here, the quickest way is to use the
`run.jl` script bundled in this repository. As a prerequisite, you need a
working C++ compiler and of course Julia.

Start Julia from this repository as follows:

julia --project=. run.jl

This will install a few required Julia packages then build all C++ code, and
finally start a Julia session with an artifact override in place which ensures
that libsingular_julia_jll picks up the copy of the C++ code that was just
compiled.

To verify the override works, check `libsingular_julia_jll.artifact_dir`; it
should point at a subdirectory of the current directory.

You can then use the Julia package manager to install or dev `Singular.jl`,
and run its test suite or perform other tests.


## Building

Compiling `libsingular-julia` from source requires a C++ enabled compiler.

The easiest way to build it is to execute the Julia script `build.jl` (which
in turn is also used by `run.jl`). For this you need to execute it in a Julia
environment in which `Singular_jll` and `CxxWrap` are installed.

Alternatively, you can also link it against your own `libcxxwrap-julia`
installation and a Singular installation, but this is more work; an
incantation like the following will do it:

```bash
git clone https://github.com/oscar-system/libsingular-julia \
cmake -DJulia_PREFIX=/home/user/path/to/julia \
-DSingular_PREFIX=/home/user/path/to/singular
-DCMAKE_INSTALL_PREFIX=home/user/prefix/for/libsingular-julia \
-DJlCxx_DIR=/home/user/path/to/libcxxwrap-julia/lib/cmake/JlCxx \
-DCMAKE_BUILD_TYPE=Release \
-S libsingular-julia -B build \

cmake --build build --config Release --target install -- -j${nproc}
```


### Overriding the default artifacts for Singular.jl

The `run.jl` script takes care of everything described below, but we document
it in case you need to do any of this manually for some reason.

Put the following into `~/.julia/artifacts/Overrides.toml` to replace the `libsingular-julia` artifact:

```toml
[ae4fbd8f-ecdb-54f8-bbce-35570499b30e]
libsingular_julia = "/home/user/prefix/for/libsingular-julia"
```

If you were using custom versions of `Singular` and/or `libcxxwrap-julia`,
then their directories used during the build need to be added as well, e.g.:

```toml
[bcd08a7b-43d2-5ff7-b6d4-c458787f915c]
Singular = "/home/user/path/to/Singular"

[3eaa8342-bff7-56a5-9981-c04077f7cee7]
libcxxwrap_julia = "/home/user/path/to/libcxxwrap-julia"
```
46 changes: 46 additions & 0 deletions deps/src/build.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Singular_jll, CxxWrap, CMake
using Singular_jll.GMP_jll, Pkg.Artifacts

# TODO: use ARGS to specify custom build dir?
builddir = "build"
installdir = abspath("install")
JlCxx_DIR = joinpath(CxxWrap.prefix_path(), "lib", "cmake", "JlCxx")

# In Julia >= 1.6, there is a "fake" GMP_jll which does not include header files;
# see <https://github.com/JuliaLang/julia/pull/38797#issuecomment-741953480>
function gmp_artifact_dir()
artifacts_toml = joinpath(dirname(dirname(Base.pathof(GMP_jll))), "StdlibArtifacts.toml")

# If this file exists, it's a stdlib JLL and we must download the artifact ourselves
if isfile(artifacts_toml)
meta = artifact_meta("GMP", artifacts_toml)
hash = Base.SHA1(meta["git-tree-sha1"])
if !artifact_exists(hash)
dl_info = first(meta["download"])
download_artifact(hash, dl_info["url"], dl_info["sha256"])
end
return artifact_path(hash)
end

# Otherwise, we can just use the artifact directory given to us by GMP_jll
return GMP_jll.find_artifact_dir()
end

const gmp_prefix = gmp_artifact_dir()
const singular_prefix = Singular_jll.artifact_dir

rm(builddir; force=true, recursive=true)

run(`$(CMake.cmake)
-DJulia_EXECUTABLE=$(joinpath(Sys.BINDIR, Base.julia_exename()))
-Dextra_cppflags=-I$(gmp_prefix)/include
-Dextra_ldflags=-L$(gmp_prefix)/lib
-DSingular_PREFIX=$(singular_prefix)
-DCMAKE_INSTALL_PREFIX=$(installdir)
-DJlCxx_DIR=$(JlCxx_DIR)
-DCMAKE_BUILD_TYPE=Release
-S .
-B $(builddir)
`)

run(`$(CMake.cmake) --build $(builddir) --config Release --target install -- -j$(Sys.CPU_THREADS)`)
Loading

0 comments on commit 14fdb93

Please sign in to comment.