From 8892fb160aa6073343efb730559cd5c813eb8d90 Mon Sep 17 00:00:00 2001 From: Greg Landrum Date: Thu, 23 Nov 2023 05:57:05 +0100 Subject: [PATCH] Fix minimal build, allow building without boost::serialization (#6932) * make sure that we can build without boost iostreams or seralization adds some "private" variables on the python side to check for these compilation flags * get out minimal cmake version correct * get minimallib js building installs an up-to-date cmake also updates the version of boost being used for the minimallib adds extra argument to allow the repo to be specified --- CMakeLists.txt | 7 +------ .../GeneralizedSubstruct/CMakeLists.txt | 2 ++ .../Wrap/testGeneralizedSubstruct.py | 19 +++++++++---------- Code/GraphMol/MolBundle.h | 2 ++ .../SubstructLibrary/SubstructLibrary.cpp | 2 ++ .../SubstructLibrary/Wrap/rough_test.py | 2 ++ .../GraphMol/SubstructLibrary/catch_tests.cpp | 2 ++ .../GraphMol/TautomerQuery/Wrap/rough_test.py | 4 +++- Code/GraphMol/TautomerQuery/catch_tests.cpp | 2 ++ Code/GraphMol/Wrap/MolBundle.cpp | 6 ++++-- Code/GraphMol/catch_molbundle.cpp | 2 ++ Code/MinimalLib/docker/Dockerfile | 10 ++++++---- Code/MinimalLib/scripts/build_rdkitjs.sh | 5 +++-- Code/RDBoost/Wrap/RDBase.cpp | 19 +++++++++++++++++++ External/CoordGen/CMakeLists.txt | 6 +++--- 15 files changed, 62 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0dba0c0e..8f68cb5a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.11) +cmake_minimum_required(VERSION 3.14) project (RDKit) @@ -456,11 +456,6 @@ if(RDK_USE_BOOST_SERIALIZATION) endif() endif() -if(RDK_BUILD_MAEPARSER_SUPPORT AND NOT RDK_USE_BOOST_IOSTREAMS) - message("Enabling RDK_USE_BOOST_IOSTREAMS because RDK_BUILD_MAEPARSER_SUPPORT is enabled.") - set(RDK_USE_BOOST_IOSTREAMS ON) -endif() - if(RDK_USE_BOOST_IOSTREAMS) target_compile_definitions(rdkit_base INTERFACE -DRDK_USE_BOOST_IOSTREAMS) find_package(Boost ${RDK_BOOST_VERSION} COMPONENTS system iostreams REQUIRED) diff --git a/Code/GraphMol/GeneralizedSubstruct/CMakeLists.txt b/Code/GraphMol/GeneralizedSubstruct/CMakeLists.txt index 3781dfb8a..409cb45ea 100644 --- a/Code/GraphMol/GeneralizedSubstruct/CMakeLists.txt +++ b/Code/GraphMol/GeneralizedSubstruct/CMakeLists.txt @@ -6,7 +6,9 @@ target_compile_definitions(GeneralizedSubstruct PRIVATE RDKIT_GENERALIZEDSUBSTRU rdkit_headers(XQMol.h DEST GraphMol/GeneralizedSubstruct) +if(RDK_USE_BOOST_SERIALIZATION) rdkit_catch_test(generalizedSubstructCatch catch_tests.cpp LINK_LIBRARIES GenericGroups FileParsers GeneralizedSubstruct) +endif() if (RDK_BUILD_PYTHON_WRAPPERS) add_subdirectory(Wrap) diff --git a/Code/GraphMol/GeneralizedSubstruct/Wrap/testGeneralizedSubstruct.py b/Code/GraphMol/GeneralizedSubstruct/Wrap/testGeneralizedSubstruct.py index acc53a3d0..dc9606726 100644 --- a/Code/GraphMol/GeneralizedSubstruct/Wrap/testGeneralizedSubstruct.py +++ b/Code/GraphMol/GeneralizedSubstruct/Wrap/testGeneralizedSubstruct.py @@ -9,11 +9,12 @@ import unittest -# from rdkit import Chem from rdkit.Chem import rdGeneralizedSubstruct +from rdkit import rdBase +@unittest.skipIf(not rdBase._serializationEnabled, "not built with serialization support") class TestCase(unittest.TestCase): def test1CreationAndSubstruct(self): @@ -116,21 +117,21 @@ class TestCase(unittest.TestCase): m = Chem.MolFromSmiles('COC1=NNC(*)=C1 |$;;;;;;AEL_p;$,LN:1:1.3|') qps = Chem.AdjustQueryParameters.NoAdjustments() qps.makeDummiesQueries = True - m = Chem.AdjustQueryProperties(m,qps) + m = Chem.AdjustQueryProperties(m, qps) Chem.SetGenericQueriesFromProperties(m) ps = Chem.SubstructMatchParameters() - ps.useGenericMatchers = True; + ps.useGenericMatchers = True mol1 = Chem.MolFromSmiles('COC1=NNC(C=C)=C1') mol2 = Chem.MolFromSmiles('COC1=NNC(CC)=C1') mol3 = Chem.MolFromSmiles('COOC1=NNC(C=C)=C1') mol4 = Chem.MolFromSmiles('COOC1=NNC(CC)=C1') - self.assertTrue(mol1.HasSubstructMatch(m,ps)) - self.assertFalse(mol2.HasSubstructMatch(m,ps)) - self.assertFalse(mol3.HasSubstructMatch(m,ps)) - self.assertFalse(mol4.HasSubstructMatch(m,ps)) - + self.assertTrue(mol1.HasSubstructMatch(m, ps)) + self.assertFalse(mol2.HasSubstructMatch(m, ps)) + self.assertFalse(mol3.HasSubstructMatch(m, ps)) + self.assertFalse(mol4.HasSubstructMatch(m, ps)) + xqm = rdGeneralizedSubstruct.CreateExtendedQueryMol(m) self.assertTrue(rdGeneralizedSubstruct.MolHasSubstructMatch(mol1, xqm, ps)) self.assertFalse(rdGeneralizedSubstruct.MolHasSubstructMatch(mol2, xqm, ps)) @@ -144,7 +145,5 @@ class TestCase(unittest.TestCase): self.assertFalse(rdGeneralizedSubstruct.MolHasSubstructMatch(mol4, xqm2, ps)) - - if __name__ == '__main__': # pragma: nocover unittest.main() diff --git a/Code/GraphMol/MolBundle.h b/Code/GraphMol/MolBundle.h index 3d3a67633..507ca388c 100644 --- a/Code/GraphMol/MolBundle.h +++ b/Code/GraphMol/MolBundle.h @@ -98,6 +98,7 @@ class MolBundle : public RDProps { //! serializes (pickles) to a stream void toStream(std::ostream &ss) const { #ifndef RDK_USE_BOOST_SERIALIZATION + RDUNUSED_PARAM(ss); PRECONDITION(0, "Boost SERIALIZATION is not enabled") #else boost::archive::text_oarchive ar(ss); @@ -113,6 +114,7 @@ class MolBundle : public RDProps { //! initializes from a stream pickle void initFromStream(std::istream &ss) { #ifndef RDK_USE_BOOST_SERIALIZATION + RDUNUSED_PARAM(ss); PRECONDITION(0, "Boost SERIALIZATION is not enabled") #else boost::archive::text_iarchive ar(ss); diff --git a/Code/GraphMol/SubstructLibrary/SubstructLibrary.cpp b/Code/GraphMol/SubstructLibrary/SubstructLibrary.cpp index 6434a6670..f0d2a981f 100644 --- a/Code/GraphMol/SubstructLibrary/SubstructLibrary.cpp +++ b/Code/GraphMol/SubstructLibrary/SubstructLibrary.cpp @@ -565,6 +565,7 @@ bool SubstructLibrary::hasMatch(const ExtendedQueryMol &query, void SubstructLibrary::toStream(std::ostream &ss) const { #ifndef RDK_USE_BOOST_SERIALIZATION + RDUNUSED_PARAM(ss); PRECONDITION(0, "Boost SERIALIZATION is not enabled") #else boost::archive::text_oarchive ar(ss); @@ -580,6 +581,7 @@ std::string SubstructLibrary::Serialize() const { void SubstructLibrary::initFromStream(std::istream &ss) { #ifndef RDK_USE_BOOST_SERIALIZATION + RDUNUSED_PARAM(ss); PRECONDITION(0, "Boost SERIALIZATION is not enabled") #else boost::archive::text_iarchive ar(ss); diff --git a/Code/GraphMol/SubstructLibrary/Wrap/rough_test.py b/Code/GraphMol/SubstructLibrary/Wrap/rough_test.py index 873189b7d..834e270c4 100644 --- a/Code/GraphMol/SubstructLibrary/Wrap/rough_test.py +++ b/Code/GraphMol/SubstructLibrary/Wrap/rough_test.py @@ -379,6 +379,7 @@ class TestCase(unittest.TestCase): self.assertEqual(lib.CountMatches(pat2), 1) print("done") + @unittest.skipIf(not rdBase._serializationEnabled, "not built with serialization support") def test_init_from_and_to_stream(self): mols = makeStereoExamples() * 10 holder = rdSubstructLibrary.CachedSmilesMolHolder() @@ -685,6 +686,7 @@ class TestCase(unittest.TestCase): pylog.setLevel(logging.WARN) rdBase.LogToCppStreams() + @unittest.skipIf(not rdBase._serializationEnabled, "not built with serialization support") def test_using_xqms(self): smis = ["COCC=O", "COOCC=O", "COOOCC=O", "COOOOCC=O"] diff --git a/Code/GraphMol/SubstructLibrary/catch_tests.cpp b/Code/GraphMol/SubstructLibrary/catch_tests.cpp index 88853171c..0ab35eb3b 100644 --- a/Code/GraphMol/SubstructLibrary/catch_tests.cpp +++ b/Code/GraphMol/SubstructLibrary/catch_tests.cpp @@ -235,6 +235,7 @@ TEST_CASE("searchOrderFunctionDemo") { } } +#ifdef RDK_USE_BOOST_SERIALIZATION TEST_CASE("ExtendedQueryMol") { std::vector libSmiles = {"COCC=O", "COOCC=O", "COOOCC=O", "COOOOCC=O"}; @@ -325,3 +326,4 @@ TEST_CASE("ExtendedQueryMol") { CHECK(!ssslib.hasMatch(xqm)); } } +#endif \ No newline at end of file diff --git a/Code/GraphMol/TautomerQuery/Wrap/rough_test.py b/Code/GraphMol/TautomerQuery/Wrap/rough_test.py index 445f9fd52..54129704d 100644 --- a/Code/GraphMol/TautomerQuery/Wrap/rough_test.py +++ b/Code/GraphMol/TautomerQuery/Wrap/rough_test.py @@ -15,9 +15,10 @@ Rough in that only basic functionality is evaluated. import os import pickle from unittest import TestCase, main - +import unittest from rdkit import Chem, DataStructs from rdkit.Chem import rdTautomerQuery +from rdkit import rdBase class TautomerQueryTestCase(TestCase): @@ -91,6 +92,7 @@ class TautomerQueryTestCase(TestCase): self.assertTrue(target.HasSubstructMatch(mol)) self.assertTrue(tautomer_query.IsSubstructOf(target)) + @unittest.skipIf(not rdBase._serializationEnabled, "not built with serialization support") def test_serialization(self): mol = Chem.MolFromSmiles("O=C1CCCCC1") base_tautomer_query = rdTautomerQuery.TautomerQuery(mol) diff --git a/Code/GraphMol/TautomerQuery/catch_tests.cpp b/Code/GraphMol/TautomerQuery/catch_tests.cpp index 627eebdb9..0582285db 100644 --- a/Code/GraphMol/TautomerQuery/catch_tests.cpp +++ b/Code/GraphMol/TautomerQuery/catch_tests.cpp @@ -375,10 +375,12 @@ TEST_CASE("Tautomer queries should propagate atom properties") { CHECK(tq->getTautomers()[0]->getAtomWithIdx(6)->hasProp("_foo")); CHECK(tq->getTautomers()[1]->getAtomWithIdx(6)->hasProp("_foo")); CHECK(tq->getTemplateMolecule().getAtomWithIdx(6)->hasProp("_foo")); +#ifdef RDK_USE_BOOST_SERIALIZATION SECTION("serialization") { TautomerQuery tq2(tq->serialize()); CHECK(tq2.getTautomers()[0]->getAtomWithIdx(6)->hasProp("_foo")); CHECK(tq2.getTautomers()[1]->getAtomWithIdx(6)->hasProp("_foo")); CHECK(tq2.getTemplateMolecule().getAtomWithIdx(6)->hasProp("_foo")); } +#endif } \ No newline at end of file diff --git a/Code/GraphMol/Wrap/MolBundle.cpp b/Code/GraphMol/Wrap/MolBundle.cpp index ebeeabe12..8bd7c8ef3 100644 --- a/Code/GraphMol/Wrap/MolBundle.cpp +++ b/Code/GraphMol/Wrap/MolBundle.cpp @@ -38,13 +38,15 @@ python::object BundleToBinary(const RDKit::MolBundle &self) { #else struct molbundle_pickle_suite : rdkit_pickle_suite { - static python::tuple getinitargs(const RDKit::MolBundle &self) { + static python::tuple getinitargs(const RDKit::MolBundle &) { throw_runtime_error("Pickling of MolBundle instances is not enabled"); + return python::tuple(); // warning suppression, we never get here }; }; -python::object BundleToBinary(const RDKit::MolBundle &self) { +python::object BundleToBinary(const RDKit::MolBundle &) { throw_runtime_error("Pickling of MolBundle instances is not enabled"); + return python::object(); // warning suppression, we never get here } #endif diff --git a/Code/GraphMol/catch_molbundle.cpp b/Code/GraphMol/catch_molbundle.cpp index ccb74bcbf..49967c0f0 100644 --- a/Code/GraphMol/catch_molbundle.cpp +++ b/Code/GraphMol/catch_molbundle.cpp @@ -41,4 +41,6 @@ TEST_CASE("MolBundle serialization") { REQUIRE(bundle.size() == nbundle.size()); } } +#else +TEST_CASE("MolBundle serialization") {} #endif \ No newline at end of file diff --git a/Code/MinimalLib/docker/Dockerfile b/Code/MinimalLib/docker/Dockerfile index 7a9077e8a..7ea7a2cd2 100644 --- a/Code/MinimalLib/docker/Dockerfile +++ b/Code/MinimalLib/docker/Dockerfile @@ -28,10 +28,12 @@ ARG RDKIT_BRANCH LABEL maintainer="Greg Landrum " +RUN echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list.d/backports.list + RUN apt-get update && apt-get upgrade -y && apt install -y \ curl \ wget \ - cmake \ + cmake/buster-backports \ python3 \ g++ \ libeigen3-dev \ @@ -41,9 +43,9 @@ RUN apt-get update && apt-get upgrade -y && apt install -y \ ENV LANG C WORKDIR /opt -RUN wget -q https://boostorg.jfrog.io/artifactory/main/release/1.67.0/source/boost_1_67_0.tar.gz && \ - tar xzf boost_1_67_0.tar.gz -WORKDIR /opt/boost_1_67_0 +RUN wget -q https://boostorg.jfrog.io/artifactory/main/release/1.72.0/source/boost_1_72_0.tar.gz && \ + tar xzf boost_1_72_0.tar.gz +WORKDIR /opt/boost_1_72_0 RUN ./bootstrap.sh --prefix=/opt/boost --with-libraries=system && \ ./b2 install diff --git a/Code/MinimalLib/scripts/build_rdkitjs.sh b/Code/MinimalLib/scripts/build_rdkitjs.sh index c43d8b0a1..191dacc0f 100644 --- a/Code/MinimalLib/scripts/build_rdkitjs.sh +++ b/Code/MinimalLib/scripts/build_rdkitjs.sh @@ -7,8 +7,9 @@ mkdir -p $MINIMALLIB_OUTPUT_PATH # Build distribution files RDKIT_BRANCH=${1:-master} -echo "Building distribution files for release $RDKIT_BRANCH" -DOCKER_BUILDKIT=1 docker build --no-cache -f Code/MinimalLib/docker/Dockerfile --build-arg RDKIT_BRANCH=$RDKIT_BRANCH -o $MINIMALLIB_OUTPUT_PATH . +RDKIT_GIT_URL=${2:-"https://github.com/rdkit/rdkit.git"} +echo "Building distribution files for release $RDKIT_BRANCH from repo $RDKIT_GIT_URL" +DOCKER_BUILDKIT=1 docker build --no-cache -f docker/Dockerfile --build-arg RDKIT_BRANCH=$RDKIT_BRANCH --build-arg RDKIT_GIT_URL=$RDKIT_GIT_URL -o $MINIMALLIB_OUTPUT_PATH . # Make files executable chmod a+rwx $MINIMALLIB_OUTPUT_PATH/RDKit_minimal.js diff --git a/Code/RDBoost/Wrap/RDBase.cpp b/Code/RDBoost/Wrap/RDBase.cpp index 15fe90565..552f176e4 100644 --- a/Code/RDBoost/Wrap/RDBase.cpp +++ b/Code/RDBoost/Wrap/RDBase.cpp @@ -286,6 +286,25 @@ BOOST_PYTHON_MODULE(rdBase) { python::scope().attr("boostVersion") = RDKit::boostVersion; python::scope().attr("rdkitBuild") = RDKit::rdkitBuild; + python::scope().attr("_serializationEnabled") = +#ifdef RDK_USE_BOOST_SERIALIZATION + true; +#else + false; +#endif + python::scope().attr("_iostreamsEnabled") = +#ifdef RDK_USE_BOOST_IOSTREAMS + true; +#else + false; +#endif + python::scope().attr("_multithreadedEnabled") = +#ifdef RDK_BUILD_THREADSAFE_SSS + true; +#else + false; +#endif + python::def("LogToCppStreams", RDLog::InitLogs, "Initialize RDKit logs with C++ streams"); python::def("LogToPythonLogger", LogToPythonLogger, diff --git a/External/CoordGen/CMakeLists.txt b/External/CoordGen/CMakeLists.txt index bfb19eabb..f771ad803 100644 --- a/External/CoordGen/CMakeLists.txt +++ b/External/CoordGen/CMakeLists.txt @@ -1,7 +1,7 @@ add_custom_target(coordgen_support ALL) include(RDKitUtils) -if(RDK_BUILD_MAEPARSER_SUPPORT) +if(RDK_BUILD_MAEPARSER_SUPPORT OR RDK_BUILD_COORDGEN_SUPPORT) if((NOT MSVC) OR RDK_INSTALL_DLLS_MSVC) add_definitions(-DIN_MAEPARSER) endif() @@ -48,11 +48,11 @@ if(RDK_BUILD_MAEPARSER_SUPPORT) set(RDK_MAEPARSER_LIBS ${maeparser_LIBRARIES} CACHE STRING "the external libraries" FORCE) -else (RDK_BUILD_MAEPARSER_SUPPORT) +else () set(RDK_MAEPARSER_LIBS CACHE STRING "the external libraries" FORCE) -endif(RDK_BUILD_MAEPARSER_SUPPORT) +endif() if(RDK_BUILD_COORDGEN_SUPPORT) if(MSVC AND (NOT RDK_INSTALL_DLLS_MSVC))