Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link against libz and pthread privately #258

Merged
merged 24 commits into from
Aug 21, 2024
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
12 changes: 8 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.11", "3.12"]
runs-on: [ubuntu-latest, macos-13, windows-latest]
python-version: ["3.11", "3.12"]
runs-on: [ubuntu-latest, macos-latest, windows-latest]

include:
- python-version: "3.12"
runs-on: macos-latest
- python-version: "3.7"
runs-on: ubuntu-latest
- python-version: "3.7"
runs-on: macos-13
- python-version: "3.7"
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
Expand Down
28 changes: 16 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.11)

if(NOT CORRECTIONLIB_VERSION)
set(CORRECTIONLIB_VERSION "0.0.0") # overriden by setup.py
endif()
string(REPLACE "." ";" VERSION_SPLIT ${CORRECTIONLIB_VERSION})
list(GET VERSION_SPLIT 0 SPLIT_VERSION_MAJOR)
list(GET VERSION_SPLIT 1 SPLIT_VERSION_MINOR)
Expand All @@ -19,16 +22,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
find_package(ZLIB)

include(CheckCXXCompilerFlag)

check_cxx_compiler_flag(-Wall has_wall)
if(has_wall)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /utf-8")
endif()


configure_file(include/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/correctionlib_version.h)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/correctionlib_version.h DESTINATION ${PKG_INSTALL}/include)
Expand All @@ -48,21 +41,32 @@ target_include_directories(correctionlib
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/pcg-cpp/include>
)
target_compile_features(correctionlib PUBLIC cxx_std_17)
if(MSVC)
target_compile_options(correctionlib PRIVATE /Zc:__cplusplus /utf-8)
else()
target_compile_options(correctionlib PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
if(ZLIB_FOUND)
target_link_libraries(correctionlib ZLIB::ZLIB)
target_link_libraries(correctionlib PRIVATE ZLIB::ZLIB)
endif()
if(Threads_FOUND AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(correctionlib Threads::Threads)
target_link_libraries(correctionlib PRIVATE Threads::Threads)
endif()
install(TARGETS correctionlib
EXPORT correctionlib-targets
LIBRARY DESTINATION ${PKG_INSTALL}/lib
ARCHIVE DESTINATION ${PKG_INSTALL}/lib
RUNTIME DESTINATION ${PKG_INSTALL}/lib
PUBLIC_HEADER DESTINATION ${PKG_INSTALL}/include
)


pybind11_add_module(_core MODULE src/python.cc)
if(MSVC)
target_compile_options(_core PRIVATE /W4 /WX)
else()
target_compile_options(_core PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
target_link_libraries(_core PRIVATE correctionlib)
set_target_properties(_core PROPERTIES BUILD_WITH_INSTALL_RPATH ON)
if (APPLE)
Expand Down
2 changes: 1 addition & 1 deletion include/version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace correction {
constexpr std::string_view correctionlib_version{"@CORRECTIONLIB_VERSION@"};
constexpr int correctionlib_major_version{@correctionlib_VERSION_MAJOR@};
constexpr int correctionlib_minor_version{@correctionlib_VERSION_MINOR@};
};
}

#endif // CORRECTIONLIB_VERSION_H
6 changes: 4 additions & 2 deletions src/correction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,11 @@ std::unique_ptr<CorrectionSet> CorrectionSet::from_file(const std::string& fn) {
if ( fp == nullptr ) {
throw std::runtime_error("Failed to open file: " + fn);
}
constexpr unsigned char magicref[4] = {0x1f, 0x8b};
constexpr unsigned char magicref[2] = {0x1f, 0x8b};
unsigned char magic[2];
fread(magic, sizeof *magic, 2, fp);
if (fread(magic, sizeof *magic, 2, fp) != 2) {
throw std::runtime_error("Failed to read file magic: " + fn);
}
rewind(fp);
char readBuffer[65536];
rapidjson::ParseResult ok;
Expand Down
13 changes: 7 additions & 6 deletions src/formula_ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace {
AstPtr peg_ast;
int pos;
std::string msg;
parser_.log = [&](size_t ln, size_t col, const std::string &themsg) {
parser_.log = [&](size_t, size_t col, const std::string &themsg) {
pos = col;
msg = themsg;
};
Expand Down Expand Up @@ -241,11 +241,12 @@ double FormulaAst::evaluate(const std::vector<Variable::Type>& values, const std
case UnaryOp::Acosh: return std::acosh(arg);
case UnaryOp::Asinh: return std::asinh(arg);
case UnaryOp::Atanh: return std::atanh(arg);
}
default: std::abort();
};
}
case NodeType::Binary: {
auto left = children_[0].evaluate(values, params);
auto right = children_[1].evaluate(values, params);
const auto left = children_[0].evaluate(values, params);
const auto right = children_[1].evaluate(values, params);
switch (std::get<BinaryOp>(data_)) {
case BinaryOp::Equal: return (left == right) ? 1. : 0.;
case BinaryOp::NotEqual: return (left != right) ? 1. : 0.;
Expand All @@ -261,9 +262,9 @@ double FormulaAst::evaluate(const std::vector<Variable::Type>& values, const std
case BinaryOp::Atan2: return std::atan2(left, right);
case BinaryOp::Max: return std::max(left, right);
case BinaryOp::Min: return std::min(left, right);
default: std::abort();
};
}
default:
std::abort(); // never reached if the switch/case is exhaustive
default: std::abort(); // never reached if the switch/case is exhaustive
}
}
78 changes: 72 additions & 6 deletions tests/test_binding.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import os
import shutil
import subprocess
import tempfile

import pytest

import correctionlib
import correctionlib.schemav2 as cs


def test_pyroot_binding():
ROOT = pytest.importorskip("ROOT")
correctionlib.register_pyroot_binding()
assert ROOT.correction.CorrectionSet

@pytest.fixture(scope="module")
def csetstr():
ptweight = cs.Correction(
name="ptweight",
version=1,
Expand All @@ -27,10 +29,74 @@ def test_pyroot_binding():
),
)
cset = cs.CorrectionSet(schema_version=2, corrections=[ptweight])
csetstr = cset.model_dump_json().replace('"', r"\"")
return cset.model_dump_json().replace('"', r"\"")


def test_pyroot_binding(csetstr: str):
ROOT = pytest.importorskip("ROOT")
correctionlib.register_pyroot_binding()
assert ROOT.correction.CorrectionSet

ROOT.gInterpreter.Declare(
f'auto cset = correction::CorrectionSet::from_string("{csetstr}");' # noqa: B907
)
ROOT.gInterpreter.Declare('auto corr = cset->at("ptweight");')
assert ROOT.corr.evaluate([1.2]) == 1.1


CMAKELIST_SRC = """\
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
project(test)
find_package(correctionlib)
add_executable(test test.cc)
target_link_libraries(test PRIVATE correctionlib)
# Because windows has no RPATH, we need to copy the DLLs to the executable directory
add_custom_command(TARGET test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy -t $<TARGET_FILE_DIR:test> $<TARGET_RUNTIME_DLLS:test>
COMMAND_EXPAND_LISTS
)
"""

TESTPROG_SRC = """\
#include "correction.h"

using correction::CorrectionSet;

int main(int argc, char** argv) {
auto cset = CorrectionSet::from_string("%s");
auto corr = cset->at("ptweight");
if (corr->evaluate({1.2}) != 1.1) {
return 1;
}
return 0;
}
"""


@pytest.mark.skipif(shutil.which("cmake") is None, reason="cmake not found")
@pytest.mark.skipif(os.name == "nt", reason="there is a segfault I cannot debug")
def test_cmake_static_compilation(csetstr: str):
with tempfile.TemporaryDirectory() as tmpdir:
cmake = os.path.join(tmpdir, "CMakeLists.txt")
with open(cmake, "w") as f:
f.write(CMAKELIST_SRC)
testprog = os.path.join(tmpdir, "test.cc")
with open(testprog, "w") as f:
f.write(TESTPROG_SRC % csetstr)
flags = (
subprocess.check_output(["correction", "config", "--cmake"])
.decode()
.split()
)
ret = subprocess.run(["cmake", "."] + flags, capture_output=True, cwd=tmpdir)
if ret.returncode != 0:
print(ret.stdout.decode())
print(ret.stderr.decode())
raise RuntimeError(f"cmake configuration failed (args: {ret.args})")
ret = subprocess.run(["cmake", "--build", "."], capture_output=True, cwd=tmpdir)
if ret.returncode != 0:
print(ret.stdout.decode())
print(ret.stderr.decode())
raise RuntimeError(f"cmake build failed (args: {ret.args})")
prog = r"Debug\test.exe" if os.name == "nt" else "test"
subprocess.run([os.path.join(tmpdir, prog)], check=True, cwd=tmpdir)
Loading