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
8 changes: 6 additions & 2 deletions .github/ci/generated-source-freshness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,13 @@ fi

# Copy the current tracked worktree content, including local tracked changes,
# without copying build products or allowing generators to touch the source.
# The copy goes through an archive file: in a pipe, bsdtar may stop reading
# at the end-of-archive marker before the writer has written its final
# padding, which fails the writer with a write error.
git -C "$repo_root" ls-files -z |
tar -C "$repo_root" --null -T - -cf - |
tar -C "$source_copy" -xf -
tar -C "$repo_root" --null -T - -cf "$workspace/source.tar"
tar -C "$source_copy" -xf "$workspace/source.tar"
rm -f -- "$workspace/source.tar"

vis_files=(
./gecode/int/var-imp/int.vis
Expand Down
117 changes: 117 additions & 0 deletions .github/ci/instance-example-smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Run the examples that read instance files on tiny files, so that their
# embedded reader specs are parsed and used.
set -euo pipefail

bin_dir="${1:?usage: instance-example-smoke.sh <bin-dir>}"
work_dir="$(mktemp -d)"
trap 'rm -rf "$work_dir"' EXIT

expect() {
local pattern="$1"
shift
local out
out="$("$@" 2>&1)" || { echo "$out"; echo "failed: $*"; exit 1; }
if ! grep -q -- "$pattern" <<<"$out"; then
echo "$out"
echo "missing '$pattern' in output of: $*"
exit 1
fi
}

# Like expect, but the command must fail
expect_error() {
local pattern="$1"
shift
local out
if out="$("$@" 2>&1)"; then
echo "$out"
echo "unexpected success: $*"
exit 1
fi
if ! grep -q -- "$pattern" <<<"$out"; then
echo "$out"
echo "missing '$pattern' in output of: $*"
exit 1
fi
}

cat > "$work_dir/sat.cnf" <<'EOF'
c x1 or x2, not x1
p cnf 2 2
1 2 0
-1 0
EOF
expect "solutions: *1" "$bin_dir/sat" "$work_dir/sat.cnf"

cat > "$work_dir/tsp.tsp" <<'EOF'
NAME : square
TYPE : TSP
DIMENSION : 4
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 0 0
2 0 10
3 10 10
4 10 0
EOF
expect "Cost: 40" "$bin_dir/tsp" "$work_dir/tsp.tsp"

cat > "$work_dir/tsptw.txt" <<'EOF'
3
0 1 2
1 0 1
2 1 0
0 100
0 100
0 100
EOF
expect "Travel time: 4" "$bin_dir/tsptw" "$work_dir/tsptw.txt"

# The spec checks the time windows
cat > "$work_dir/tsptw-window.txt" <<'EOF'
2
0 1
1 0
0 10
5 4
EOF
expect_error "the time window of a node is invalid" "$bin_dir/tsptw" "$work_dir/tsptw-window.txt"

cat > "$work_dir/job-shop.txt" <<'EOF'
# two jobs on two machines
2 2
0 3 1 2
1 2 0 1
EOF
expect "makespan: 5" "$bin_dir/job-shop" -probes 0 "$work_dir/job-shop.txt"

# The spec checks that the machines exist
cat > "$work_dir/job-shop-machine.txt" <<'EOF'
2 2
0 3 2 2
1 2 0 1
EOF
expect_error "expected an int in 0..1, found '2'" "$bin_dir/job-shop" -probes 0 "$work_dir/job-shop-machine.txt"

cat > "$work_dir/sudoku.txt" <<'EOF'
# size=4 box=2x2
1...
..1.
.1..
...1
EOF
expect "solutions: *1" "$bin_dir/sudoku" "$work_dir/sudoku.txt"

cat > "$work_dir/nonogram.non" <<'EOF'
catalogue "smoke"
width 2
height 2
rows
2
1
columns
2
1
EOF
expect "solutions: *1" "$bin_dir/nonogram" "$work_dir/nonogram.non"
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ jobs:
shell: bash
run: bash .github/ci/cmake-example-feature-smoke.sh

- name: Examples reading instance files
shell: bash
run: bash .github/ci/instance-example-smoke.sh "$GITHUB_WORKSPACE/build-ninja/bin"

- name: Check
shell: bash
run: >
Expand Down
49 changes: 45 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ option(GECODE_ENABLE_INT_VARS "Build int variables module" ON)
option(GECODE_ENABLE_SET_VARS "Build set variables module" ON)
option(GECODE_ENABLE_FLOAT_VARS "Build float variables module" ON)
option(GECODE_ENABLE_MINIMODEL "Build minimodel module" ON)
option(GECODE_ENABLE_INSTANCE "Build instance reader module" ON)
option(GECODE_ENABLE_DRIVER "Build driver module" ON)
option(GECODE_ENABLE_FLATZINC "Build FlatZinc module" ON)

Expand Down Expand Up @@ -271,6 +272,16 @@ if(GECODE_ENABLE_EXAMPLES)
gecode_force_option_on(GECODE_ENABLE_MINIMODEL "Examples require minimodel")
gecode_force_option_on(GECODE_ENABLE_DRIVER "Examples require driver")
endif()
# After every block that can enable the driver
if(GECODE_ENABLE_DRIVER)
gecode_force_option_on(GECODE_ENABLE_INSTANCE "Driver requires instance reader")
endif()
# The instance reader returns IntArgs. Leave it out of builds without int
# variables rather than enable them (the driver has enabled them already).
if(GECODE_ENABLE_INSTANCE AND NOT GECODE_ENABLE_INT_VARS)
message(STATUS "Disabling GECODE_ENABLE_INSTANCE: instance reader requires int variables")
set(GECODE_ENABLE_INSTANCE OFF)
endif()

include(CheckCXXCompilerFlag)
set(GECODE_VISIBILITY_COMPILE_OPTION)
Expand Down Expand Up @@ -985,7 +996,7 @@ HAVE_DOT = ${GECODE_DOXYGEN_DOT}
")

set(GECODE_DOC_SOURCE_INPUTS)
foreach(component SUPPORT KERNEL SEARCH INT SET FLOAT MINIMODEL DRIVER GIST FLATZINC TEST)
foreach(component SUPPORT KERNEL SEARCH INT SET FLOAT MINIMODEL INSTANCE DRIVER GIST FLATZINC TEST)
list(APPEND GECODE_DOC_SOURCE_INPUTS ${GECODE_${component}_SOURCES})
endforeach()
list(APPEND GECODE_DOC_SOURCE_INPUTS ${GECODE_FLATZINC_EXE_SOURCE})
Expand Down Expand Up @@ -1129,6 +1140,9 @@ endif()
if(GECODE_ENABLE_MINIMODEL)
list(APPEND GECODE_LIBRARY_COMPONENTS minimodel)
endif()
if(GECODE_ENABLE_INSTANCE)
list(APPEND GECODE_LIBRARY_COMPONENTS instance)
endif()
if(GECODE_ENABLE_DRIVER)
list(APPEND GECODE_LIBRARY_COMPONENTS driver)
endif()
Expand Down Expand Up @@ -1311,8 +1325,11 @@ if(GECODE_ENABLE_MINIMODEL)
endif()
gecode_link_component(minimodel ${mm_deps})
endif()
if(GECODE_ENABLE_INSTANCE)
gecode_link_component(instance int)
endif()
if(GECODE_ENABLE_DRIVER)
set(driver_deps int search)
set(driver_deps int search instance)
if(GECODE_ENABLE_MINIMODEL)
list(APPEND driver_deps minimodel)
endif()
Expand Down Expand Up @@ -1362,7 +1379,7 @@ endif()

# Compatibility aggregate target for downstream projects expecting Gecode::gecode.
add_library(gecode INTERFACE)
foreach(component IN ITEMS support kernel search int set float minimodel driver flatzinc gist)
foreach(component IN ITEMS support kernel search int set float minimodel instance driver flatzinc gist)
if(TARGET gecode${component})
target_link_libraries(gecode INTERFACE gecode${component})
endif()
Expand All @@ -1387,6 +1404,21 @@ if(GECODE_ENABLE_FLATZINC)
list(APPEND GECODE_INSTALL_TARGETS fzn-gecode)
endif()

if(GECODE_ENABLE_INSTANCE)
add_executable(gecode-instance ${GECODE_INSTANCE_EXE_SOURCE})
# The int headers include the search headers, whose inline code can refer
# to the search library in unoptimized builds
target_link_libraries(gecode-instance PRIVATE gecodeinstance gecodesearch)
if(APPLE)
set_target_properties(gecode-instance PROPERTIES
INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR}")
elseif(UNIX)
set_target_properties(gecode-instance PROPERTIES
INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
endif()
list(APPEND GECODE_INSTALL_TARGETS gecode-instance)
endif()

if(BUILD_TESTING)
set(GECODE_CAN_BUILD_TEST_HARNESS TRUE)
foreach(required search int)
Expand Down Expand Up @@ -1489,6 +1521,9 @@ if(BUILD_TESTING)
if(NOT GECODE_ENABLE_FLATZINC)
list(FILTER GECODE_TEST_SOURCES_SELECTED EXCLUDE REGEX "^test/flatzinc(/|\\.cpp)")
endif()
if(NOT TARGET gecodeinstance)
list(REMOVE_ITEM GECODE_TEST_SOURCES_SELECTED test/instance.cpp)
endif()

if(GECODE_CAN_BUILD_TESTS)
add_executable(gecode-test EXCLUDE_FROM_ALL ${GECODE_TEST_MAIN_SOURCE} ${GECODE_TEST_SOURCES_SELECTED})
Expand All @@ -1501,6 +1536,9 @@ if(BUILD_TESTING)
if(TARGET gecodetestfloat)
list(APPEND GECODE_TEST_LINK_LIBS gecodetestfloat)
endif()
if(TARGET gecodeinstance)
list(APPEND GECODE_TEST_LINK_LIBS gecodeinstance gecodedriver)
endif()
if(GECODE_ENABLE_FLATZINC)
list(APPEND GECODE_TEST_LINK_LIBS gecodeflatzinc)
endif()
Expand Down Expand Up @@ -1710,6 +1748,8 @@ if(GECODE_INSTALL)
PATTERN "flatzinc/blackbox.hh" EXCLUDE
PATTERN "flatzinc/blackbox-backend.hh" EXCLUDE
PATTERN "flatzinc/blackbox-process.hh" EXCLUDE
PATTERN "instance/eval.hpp" EXCLUDE
PATTERN "instance/impl.hpp" EXCLUDE
PATTERN "exampleplugin" EXCLUDE
PATTERN "standalone-example" EXCLUDE
PATTERN "abi*" EXCLUDE)
Expand Down Expand Up @@ -1822,7 +1862,8 @@ foreach(gecode_option IN ITEMS
GECODE_ENABLE_EXPERIMENTAL
GECODE_ENABLE_EXAMPLES GECODE_INSTALL
GECODE_ENABLE_SEARCH GECODE_ENABLE_INT_VARS GECODE_ENABLE_SET_VARS
GECODE_ENABLE_FLOAT_VARS GECODE_ENABLE_MINIMODEL GECODE_ENABLE_DRIVER
GECODE_ENABLE_FLOAT_VARS GECODE_ENABLE_MINIMODEL GECODE_ENABLE_INSTANCE
GECODE_ENABLE_DRIVER
GECODE_ENABLE_FLATZINC GECODE_ENABLE_ALLOCATOR GECODE_ENABLE_MIMALLOC GECODE_ENABLE_AUDIT
GECODE_ENABLE_FAULT_INJECTION GECODE_REGENERATE_VARIMP
GECODE_DOC_SEARCH GECODE_DOC_TAGFILE)
Expand Down
Loading
Loading