* add test export heder to gitignore

* define export macros in separate file

* install new header

* patch GA with the new macros

* fix struct declarations

* fix conformerparser exports

* fix MolSGroupParsing ParseV3000Array export

* fix java wrappers

* export exceptions

* remove duplicated exports

* Build RDGeneral exceptions into lib

* export queries, only for *nix

* fix RingDecomposerLib header manipulation

* fix CIP labeler test issues
This commit is contained in:
Ric
2021-02-15 08:29:04 -05:00
committed by GitHub
parent bd00fda39e
commit c9199cf1da
34 changed files with 150 additions and 93 deletions

1
.gitignore vendored
View File

@@ -36,6 +36,7 @@ __pycache__/
/Code/RDBoost/test.h
/Code/RDGeneral/RDConfig.h
/Code/RDGeneral/export.h
/Code/RDGeneral/test.h
/Code/RDGeneral/versions.h
/Code/RDGeneral/versions.cpp

View File

@@ -19,10 +19,10 @@ namespace ForceFields {
namespace MMFF {
//! An angle range constraint modelled after a AngleBendContrib
class RDKIT_FORCEFIELD_EXPORT RDKIT_FORCEFIELD_EXPORT AngleConstraintContrib
class RDKIT_FORCEFIELD_EXPORT AngleConstraintContrib
: public ForceFieldContrib {
public:
AngleConstraintContrib() {};
AngleConstraintContrib(){};
//! Constructor
/*!
\param owner pointer to the owning ForceField
@@ -53,7 +53,8 @@ class RDKIT_FORCEFIELD_EXPORT RDKIT_FORCEFIELD_EXPORT AngleConstraintContrib
};
private:
int d_at1Idx{-1}, d_at2Idx{-1}, d_at3Idx{-1}; //!< indices of atoms forming the angle
int d_at1Idx{-1}, d_at2Idx{-1},
d_at3Idx{-1}; //!< indices of atoms forming the angle
double d_minAngleDeg, d_maxAngleDeg; //!< rest amplitudes of the angle
double d_forceConstant; //!< force constant of the angle constraint
};

View File

@@ -25,11 +25,9 @@ namespace MMFF {
class MMFFTor;
//! the torsion term for MMFF
class RDKIT_FORCEFIELD_EXPORT RDKIT_FORCEFIELD_EXPORT TorsionAngleContrib
: public ForceFieldContrib {
class RDKIT_FORCEFIELD_EXPORT TorsionAngleContrib : public ForceFieldContrib {
public:
TorsionAngleContrib()
{};
TorsionAngleContrib(){};
//! Constructor
/*!
The torsion is between atom1 - atom2 - atom3 - atom4

View File

@@ -19,11 +19,10 @@ namespace ForceFields {
namespace MMFF {
//! A dihedral angle range constraint modelled after a TorsionContrib
class RDKIT_FORCEFIELD_EXPORT RDKIT_FORCEFIELD_EXPORT TorsionConstraintContrib
class RDKIT_FORCEFIELD_EXPORT TorsionConstraintContrib
: public ForceFieldContrib {
public:
TorsionConstraintContrib()
{};
TorsionConstraintContrib(){};
//! Constructor
/*!
\param owner pointer to the owning ForceField
@@ -55,9 +54,10 @@ class RDKIT_FORCEFIELD_EXPORT RDKIT_FORCEFIELD_EXPORT TorsionConstraintContrib
};
private:
void setParameters(ForceField *owner, unsigned int idx1,
unsigned int idx2, unsigned int idx3, unsigned int idx4,
double minDihedralDeg, double maxDihedralDeg, double forceConst);
void setParameters(ForceField *owner, unsigned int idx1, unsigned int idx2,
unsigned int idx3, unsigned int idx4,
double minDihedralDeg, double maxDihedralDeg,
double forceConst);
double computeDihedralTerm(double dihedral) const;
int d_at1Idx{-1}, d_at2Idx{-1}, d_at3Idx{-1},
d_at4Idx{-1}; //!< indices of atoms forming the dihedral angle

View File

@@ -19,7 +19,7 @@ class ROMol;
class RWMol;
namespace Abbreviations {
RDKIT_ABBREVIATIONS_EXPORT struct AbbreviationDefinition {
struct RDKIT_ABBREVIATIONS_EXPORT AbbreviationDefinition {
std::string label;
std::string displayLabel;
std::string displayLabelW;
@@ -34,7 +34,7 @@ RDKIT_ABBREVIATIONS_EXPORT struct AbbreviationDefinition {
return !(*this == other);
}
};
RDKIT_ABBREVIATIONS_EXPORT struct AbbreviationMatch {
struct RDKIT_ABBREVIATIONS_EXPORT AbbreviationMatch {
std::vector<std::pair<int, int>> match;
AbbreviationDefinition abbrev;
AbbreviationMatch(const std::vector<std::pair<int, int>>& matchArg,

View File

@@ -25,6 +25,7 @@ rdkit_library(CIPLabeler
target_compile_definitions(CIPLabeler PRIVATE RDKIT_CIPLABELER_BUILD)
rdkit_headers(CIPLabeler.h
TooManyNodesException.h
DEST CIPLabeler)
rdkit_catch_test(testCIPLabeler catch_tests.cpp
@@ -33,15 +34,13 @@ rdkit_catch_test(testCIPLabeler catch_tests.cpp
${configs_src} ${rules_src}
LINK_LIBRARIES SmilesParse GraphMol)
# Set the BUILD macro to keep dll linkage consistency, since, in order
# to test private, unexported functions, we are building the test from
# sources, and NOT linking to the lib.
if(RDK_BUILD_CPP_TESTS)
target_compile_definitions(testCIPLabeler PRIVATE RDKIT_CIPLABELER_BUILD)
endif()
if(RDK_BUILD_PYTHON_WRAPPERS)
add_subdirectory(Wrap)
endif()

View File

@@ -13,13 +13,16 @@
#include <stdexcept>
#include <string>
#include <RDGeneral/export.h>
namespace RDKit {
namespace CIPLabeler {
class TooManyNodesException : public std::runtime_error {
public:
class RDKIT_CIPLABELER_EXPORT TooManyNodesException
: public std::runtime_error {
public:
TooManyNodesException(const std::string &msg) : std::runtime_error(msg){};
};
} // namespace CIPLabeler
} // namespace RDKit
} // namespace CIPLabeler
} // namespace RDKit

View File

@@ -25,7 +25,8 @@ namespace RDKit {
const int MOLFILE_MAXLINE = 256;
RDKIT_FILEPARSERS_EXPORT std::string strip(const std::string &orig);
class MolFileUnhandledFeatureException : public std::exception {
class RDKIT_FILEPARSERS_EXPORT MolFileUnhandledFeatureException
: public std::exception {
public:
//! construct with an error message
explicit MolFileUnhandledFeatureException(const char *msg) : _msg(msg){};

View File

@@ -129,7 +129,8 @@ void ParseSGroupV2000SBTLine(IDX_TO_SGROUP_MAP &sGroupMap, RWMol *mol,
/* ------------------ V3000 Utils ------------------ */
template <class T>
std::vector<T> ParseV3000Array(std::stringstream &stream);
RDKIT_FILEPARSERS_EXPORT std::vector<T> ParseV3000Array(
std::stringstream &stream);
#if defined(WIN32) && defined(RDKIT_DYN_LINK)
template RDKIT_FILEPARSERS_EXPORT std::vector<int> ParseV3000Array(
std::stringstream &);

View File

@@ -11,10 +11,11 @@
#include <RDGeneral/export.h>
#include <exception>
#include <string>
namespace RDKit {
class GenericRDKitException : public std::exception {
class RDKIT_RDGENERAL_EXPORT GenericRDKitException : public std::exception {
public:
GenericRDKitException(const std::string &i) : _value(i){};
GenericRDKitException(const char *msg) : _value(msg){};

View File

@@ -70,6 +70,7 @@
%include <boost/smart_ptr/shared_array.hpp>
/* undefine RDKIT_<LIBNAME>_EXPORT macros */
%include <RDGeneral/RDExportMacros.h>
%include <RDGeneral/export.h>
/* Include the base types before anything that will utilize them */
#ifdef SWIGWIN

View File

@@ -69,6 +69,7 @@
%include <boost/smart_ptr/shared_array.hpp>
/* undefine RDKIT_<LIBNAME>_EXPORT macros */
%include <RDGeneral/RDExportMacros.h>
%include <RDGeneral/export.h>
/* Include the base types before anything that will utilize them */
#ifdef SWIGWIN

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! a Query implementing AND: requires all children to be \c true
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class AndQuery
class RDKIT_QUERY_EXPORT AndQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
typedef Query<MatchFuncArgType, DataFuncArgType, needsConversion> BASE;

View File

@@ -20,7 +20,7 @@ namespace Queries {
template <typename MatchFuncArgType,
typename DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class EqualityQuery
class RDKIT_QUERY_EXPORT EqualityQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
EqualityQuery() { this->df_negate = false; };

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! value (and an optional tolerance)
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class GreaterEqualQuery
class RDKIT_QUERY_EXPORT GreaterEqualQuery
: public EqualityQuery<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
GreaterEqualQuery() { this->d_tol = 0; };

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! value (and an optional tolerance)
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class GreaterQuery
class RDKIT_QUERY_EXPORT GreaterQuery
: public EqualityQuery<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
GreaterQuery() { this->d_tol = 0; };

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! value (and an optional tolerance)
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class LessEqualQuery
class RDKIT_QUERY_EXPORT LessEqualQuery
: public EqualityQuery<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
LessEqualQuery() { this->d_tol = 0; };

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! value (and an optional tolerance)
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class LessQuery
class RDKIT_QUERY_EXPORT LessQuery
: public EqualityQuery<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
LessQuery() { this->d_tol = 0; };

View File

@@ -17,7 +17,7 @@ namespace Queries {
//! a Query implementing AND: requires any child to be \c true
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class OrQuery
class RDKIT_QUERY_EXPORT OrQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
typedef Query<MatchFuncArgType, DataFuncArgType, needsConversion> BASE;

View File

@@ -42,7 +42,7 @@ class Int2Type {
*/
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class Query {
class RDKIT_QUERY_EXPORT Query {
public:
typedef std::shared_ptr<
Query<MatchFuncArgType, DataFuncArgType, needsConversion>>

View File

@@ -24,7 +24,7 @@ namespace Queries {
//! There is also an optional tolerance to be used in comparisons
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class RangeQuery
class RDKIT_QUERY_EXPORT RangeQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
RangeQuery() : d_upper(0), d_lower(0) { this->df_negate = false; };

View File

@@ -22,7 +22,7 @@ namespace Queries {
//!
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class SetQuery
class RDKIT_QUERY_EXPORT SetQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
typedef std::set<MatchFuncArgType> CONTAINER_TYPE;

View File

@@ -18,7 +18,7 @@ namespace Queries {
//! a Query implementing XOR: requires exactly one child to be \c true
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class XOrQuery
class RDKIT_QUERY_EXPORT XOrQuery
: public Query<MatchFuncArgType, DataFuncArgType, needsConversion> {
public:
typedef Query<MatchFuncArgType, DataFuncArgType, needsConversion> BASE;

View File

@@ -18,7 +18,7 @@
namespace RDKit {
//! used by various file parsing classes to indicate a bad file
class BadFileException : public std::runtime_error {
class RDKIT_RDGENERAL_EXPORT BadFileException : public std::runtime_error {
public:
//! construct with an error message
explicit BadFileException(const char *msg)

View File

@@ -7,7 +7,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/RDConfig.h.cmake
rdkit_library(RDGeneral
Invariant.cpp types.cpp utils.cpp RDLog.cpp
Invariant.cpp types.cpp utils.cpp RDGeneralExceptions.cpp RDLog.cpp
LocaleSwitcher.cpp versions.cpp SHARED)
target_compile_definitions(RDGeneral PRIVATE RDKIT_RDGENERAL_BUILD)
@@ -62,6 +62,7 @@ rdkit_headers(Exceptions.h
LocaleSwitcher.h
Ranking.h
hanoiSort.h
RDExportMacros.h
export.h
test.h
ConcurrentQueue.h

View File

@@ -16,7 +16,7 @@
//! \brief Class to allow us to throw an \c IndexError from C++ and have
//! it make it back to Python
//!
class IndexErrorException : public std::runtime_error {
class RDKIT_RDGENERAL_EXPORT IndexErrorException : public std::runtime_error {
public:
IndexErrorException(int i)
: std::runtime_error("IndexErrorException"),
@@ -36,7 +36,7 @@ class IndexErrorException : public std::runtime_error {
//! \brief Class to allow us to throw a \c ValueError from C++ and have
//! it make it back to Python
//!
class ValueErrorException : public std::runtime_error {
class RDKIT_RDGENERAL_EXPORT ValueErrorException : public std::runtime_error {
public:
ValueErrorException(const std::string& i)
: std::runtime_error("ValueErrorException"), _value(i){};
@@ -52,7 +52,7 @@ class ValueErrorException : public std::runtime_error {
//! \brief Class to allow us to throw a \c KeyError from C++ and have
//! it make it back to Python
//!
class KeyErrorException : public std::runtime_error {
class RDKIT_RDGENERAL_EXPORT KeyErrorException : public std::runtime_error {
public:
KeyErrorException(std::string key)
: std::runtime_error("KeyErrorException"),

View File

@@ -16,7 +16,7 @@
namespace RDKit {
//! used by various file parsing classes to indicate a parse error
class FileParseException : public std::runtime_error {
class RDKIT_RDGENERAL_EXPORT FileParseException : public std::runtime_error {
public:
//! construct with an error message
explicit FileParseException(const char *msg)

View File

@@ -0,0 +1,40 @@
//
// Copyright (C) 2021 Schrödinger, LLC
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
#pragma once
#ifndef SWIG
#ifdef _MSC_VER
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
#endif
#include <boost/config.hpp>
// RDKit export macro definitions
#ifdef RDKIT_DYN_LINK
#if defined( WIN32 ) && defined( _MSC_VER ) && defined( BOOST_HAS_DECLSPEC )
#define RDKIT_EXPORT_API __declspec(dllexport)
#define RDKIT_IMPORT_API __declspec(dllimport)
#elif __GNUC__ >= 4 || defined( __clang__ )
#define RDKIT_EXPORT_API __attribute__((visibility("default")))
#define RDKIT_IMPORT_API __attribute__((visibility("default")))
#endif // WIN32
#endif // RDKIT_DYN_LINK
// RDKit end export macro definitions
#endif // SWIG
#ifndef RDKIT_EXPORT_API
#define RDKIT_EXPORT_API
#endif
#ifndef RDKIT_IMPORT_API
#define RDKIT_IMPORT_API
#endif

View File

@@ -0,0 +1,18 @@
//
// Copyright (C) 2021 Schrödinger, LLC
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
/*
* This file is just to make sure exceptions in this directory
* get built into the library.
*/
#include "BadFileException.h"
#include "Exceptions.h"
#include "FileParseException.h"

View File

@@ -243,16 +243,9 @@ function(createExportTestHeaders)
list(SORT exportLibs)
set(exportPath "Code/RDGeneral/export.h")
file(WRITE "${CMAKE_BINARY_DIR}/${exportPath}.tmp"
"// auto-generated __declspec definition header\n"
"// auto-generated export definition header\n"
"#pragma once\n"
"#ifndef SWIG\n"
"#ifdef _MSC_VER\n"
"#pragma warning(disable:4251)\n"
"#pragma warning(disable:4275)\n"
"#endif\n"
"\n"
"#include <boost/config.hpp>\n"
"#endif\n")
"#include <RDGeneral/RDExportMacros.h>\n")
set(testPath "Code/RDGeneral/test.h")
file(WRITE "${CMAKE_BINARY_DIR}/${testPath}.tmp"
"// auto-generated header to be imported in all cpp tests\n"
@@ -262,15 +255,10 @@ function(createExportTestHeaders)
file(APPEND "${CMAKE_BINARY_DIR}/${exportPath}.tmp"
"\n"
"// RDKIT_${exportLib}_EXPORT definitions\n"
"#if defined(BOOST_HAS_DECLSPEC) && defined(RDKIT_DYN_LINK) && !defined(SWIG)\n"
"#ifdef RDKIT_${exportLib}_BUILD\n"
"#define RDKIT_${exportLib}_EXPORT __declspec(dllexport)\n"
"#define RDKIT_${exportLib}_EXPORT RDKIT_EXPORT_API\n"
"#else\n"
"#define RDKIT_${exportLib}_EXPORT __declspec(dllimport)\n"
"#endif\n"
"#endif\n"
"#ifndef RDKIT_${exportLib}_EXPORT\n"
"#define RDKIT_${exportLib}_EXPORT\n"
"#define RDKIT_${exportLib}_EXPORT RDKIT_IMPORT_API\n"
"#endif\n"
"// RDKIT_${exportLib}_EXPORT end definitions\n")
file(APPEND "${CMAKE_BINARY_DIR}/${testPath}.tmp"
@@ -279,6 +267,19 @@ function(createExportTestHeaders)
"#undef RDKIT_${exportLib}_BUILD\n"
"#endif\n")
endforeach()
file(APPEND "${CMAKE_BINARY_DIR}/${exportPath}.tmp"
"\n"
"/*\n"
" * Do not dll export/import to export queries (it will mess up with the\n"
" * templates), but make sure it is visible for *nix\n"
" */\n"
"// RDKIT_QUERY_EXPORT definitions\n"
"#if defined(RDKIT_DYN_LINK) && defined(WIN32) && defined(_MSC_VER) && defined(BOOST_HAS_DECLSPEC)\n"
"#define RDKIT_QUERY_EXPORT\n"
"#else\n"
"#define RDKIT_QUERY_EXPORT RDKIT_GRAPHMOL_EXPORT\n"
"#endif\n"
"// RDKIT_QUERY_EXPORT end definitions\n")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_BINARY_DIR}/${exportPath}.tmp" "${CMAKE_SOURCE_DIR}/${exportPath}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different

View File

@@ -1,10 +1,10 @@
rdkit_library(ConformerParser ConformerParser.cpp
LINK_LIBRARIES GraphMol)
target_compile_definitions(SmilesParse PRIVATE RDKIT_CONFORMERPARSER_BUILD)
rdkit_test(testConformerParser test.cpp
LINK_LIBRARIES ConformerParser
FileParsers SmilesParse
GraphMol RDGeometryLib RDGeneral)
rdkit_test(testConformerParser test.cpp
LINK_LIBRARIES ConformerParser FileParsers SmilesParse
GraphMol RDGeometryLib RDGeneral)
if(RDK_BUILD_PYTHON_WRAPPERS)
add_subdirectory(Wrap)

View File

@@ -15,7 +15,8 @@
// with the distribution.
// * Neither the name of Novartis Institutes for BioMedical Research Inc.
// nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -40,7 +41,7 @@
#include <sstream>
namespace RDKit{
namespace RDKit {
class ROMol;
class Conformer;
namespace ConformerParser {
@@ -54,8 +55,9 @@ namespace ConformerParser {
Returns: integer vector with confIds
*/
INT_VECT addConformersFromList(ROMol &mol, const std::vector<std::vector<double> > &coords,
int numConf=-1);
RDKIT_CONFORMERPARSER_EXPORT INT_VECT addConformersFromList(
ROMol &mol, const std::vector<std::vector<double>> &coords,
int numConf = -1);
/*!
Converts an Amber trajectory into a list of doubles
@@ -64,10 +66,11 @@ INT_VECT addConformersFromList(ROMol &mol, const std::vector<std::vector<double>
\param coords list with coordinates
*/
void readAmberTrajectory(const std::string &fName, std::vector<std::vector<double> > &coords,
unsigned int numAtoms);
RDKIT_CONFORMERPARSER_EXPORT void readAmberTrajectory(
const std::string &fName, std::vector<std::vector<double>> &coords,
unsigned int numAtoms);
} // end namespace ConformerParser
} // end namespace RDKit
} // end namespace ConformerParser
} // end namespace RDKit
#endif

View File

@@ -9,20 +9,7 @@
//
#pragma once
#ifndef SWIG
# ifdef _MSC_VER
# pragma warning(disable : 4251)
# pragma warning(disable : 4275)
# endif
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_DECLSPEC) && defined(RDKIT_DYN_LINK) && !defined(SWIG)
# define GA_EXPORT __declspec(dllexport)
#endif
#ifndef GA_EXPORT
# define GA_EXPORT
#endif
#include <RDGeneral/RDExportMacros.h>
#define GA_EXPORT RDKIT_EXPORT_API

View File

@@ -28,8 +28,8 @@ file(GLOB URFSOURCES "${URFLIB_DIR}/*.c")
if((MSVC AND RDK_INSTALL_DLLS_MSVC) OR ((NOT MSVC) AND WIN32))
set (ringdecomposerlib_h ${URFLIB_DIR}/RingDecomposerLib.h)
file(READ ${ringdecomposerlib_h} ringdecomposerlib_h_data)
if (NOT "${ringdecomposerlib_h_data}" STREQUAL "RDKIT_URFLIB_BUILD")
string(REGEX REPLACE "([ ]*)(#define[ ]+RDL_API[ ]+__declspec)(\\([ ]*dllexport[ ]*\\))" "\\1#ifdef RDKIT_URFLIB_BUILD\n\\1\\2\\3\n\\1#else\n\\1\\2(dllimport)\n\\1#endif" ringdecomposerlib_h_data "${ringdecomposerlib_h_data}")
if (NOT "${ringdecomposerlib_h_data}" MATCHES "RDKIT_URFLIB_BUILD")
string(REGEX REPLACE "([ ]*)(#define[ ]+RDL_API[ ]+__declspec)(\\([ ]*dllexport[ ]*\\))" "\\1#ifdef RDKIT_URFLIB_BUILD\n\\1\\1\\2\\3\n\\1#else\n\\1\\1\\2(dllimport)\n\\1#endif" ringdecomposerlib_h_data "${ringdecomposerlib_h_data}")
file(WRITE ${ringdecomposerlib_h} "${ringdecomposerlib_h_data}")
endif()
endif()