import imp_module from SCons.Script import Glob, Dir, File, Builder, Action, Exit import os import sys import re def _action_config_h(target, source, env): """The IMPModuleConfig Builder generates a configuration header file used to mark classes and functions for export and to define namespaces, and a corresponding SWIG interface, e.g. env.IMPModuleConfig(('config.h', 'foo_config.i'), env.Value('foo')) generates a configuration header and interface for the 'foo' module.""" vars= imp_module.make_vars(env) #print "opening h at " +target[0].abspath + " for module %(module)s"%vars h = file(target[0].abspath, 'w') #print "Generating "+str(h) print >> h, """/* * \\file %(module_include_path)s/%(module)s_config.h * \\brief Provide macros to mark functions and classes as exported * from a DLL/.so, and to set up namespaces * * When building the module, %(PREPROC)s_EXPORTS should be defined, and when * using the module externally, it should not be. Classes and functions * defined in the module's headers should then be marked with * %(PREPROC)sEXPORT if they are intended to be part of the API, or with * %(PREPROC)sLOCAL if they are not (the latter is the default). * * The Windows build environment requires applications to mark exports in * this way; we use the same markings to set the visibility of ELF symbols * if we have compiler support. * * All code in this module should live in the %(namespace)s namespace. * This is simply achieved by wrapping things with the * %(PREPROC)s_BEGIN_NAMESPACE and %(PREPROC)s_END_NAMESPACE macros. * There are similar macros for module code that is designed to be for * internal use only. * * This header is auto-generated by tools/imp-module.py; it should not be * edited manually. * * Copyright 2007-2010 IMP Inventors. All rights reserved. * */ #ifndef %(PREPROC)s_CONFIG_H #define %(PREPROC)s_CONFIG_H #include #ifdef _MSC_VER #ifdef %(PREPROC)s_EXPORTS #define %(PREPROC)sEXPORT __declspec(dllexport) #else #define %(PREPROC)sEXPORT __declspec(dllimport) #endif #define %(PREPROC)sLOCAL #else #ifdef GCC_VISIBILITY #define %(PREPROC)sEXPORT __attribute__ ((visibility("default"))) #define %(PREPROC)sLOCAL __attribute__ ((visibility("hidden"))) #else #define %(PREPROC)sEXPORT #define %(PREPROC)sLOCAL #endif #endif #if _MSC_VER && !defined(SWIG) && !defined(IMP_DOXYGEN) #ifdef %(PREPROC)s_EXPORTS #define %(PREPROC)s_EXPORT_TEMPLATE(name) \ template class __declspec(dllexport) name #else #define %(PREPROC)s_EXPORT_TEMPLATE(name) \ template class __declspec(dllimport) name #endif #else #define %(PREPROC)s_EXPORT_TEMPLATE(name) #endif """ % vars print >> h, "#define %(PREPROC)s_BEGIN_NAMESPACE \\"%vars for comp in vars['namespace'].split("::"): print >> h, "namespace %s {\\" %comp print >> h print >> h, "#define %(PREPROC)s_END_NAMESPACE \\"%vars for comp in vars['namespace'].split("::"): print >> h, "} /* namespace %s */ \\" %comp print >> h print >> h, """#define %(PREPROC)s_BEGIN_INTERNAL_NAMESPACE \\ %(PREPROC)s_BEGIN_NAMESPACE \\ namespace internal { """ %vars print >> h print >> h, """#define %(PREPROC)s_END_INTERNAL_NAMESPACE \\ } /* namespace internal */ \\ %(PREPROC)s_END_NAMESPACE """ %vars print >> h for d in env['IMP_MODULE_CONFIG']: if type(d) == type([]): name=d[0] value=d[1] else: name=d value=None nd= name.replace("_USE_","_NO_") if nd==name: nd= name.replace("_NO_", "_USE_") if nd != name: print >> h, "#ifdef "+nd print >> h, "/* Do not define IMP config macros directly */" print >> h, "BOOST_STATIC_ASSERT(false)" print >> h, "#endif" print >> h, "#ifdef "+name print >> h, "/* Do not define IMP config macros directly */" print >> h, "BOOST_STATIC_ASSERT(false)" print >> h, "#endif" if value is not None: print >> h, "#define "+name+" "+value else: print >> h, "#define "+name print >> h # This needs to be called get_module_version_info() to make it easy # to call from Objects (which have their own get_version_info() method print >> h, """ // functions are defined explicitly for swig #ifndef SWIG namespace IMP { class VersionInfo; } #include #include #include IMP_BEGIN_INTERNAL_NAMESPACE IMPEXPORT std::string get_data_path(std::string module_name, std::string file_name); IMPEXPORT std::string get_example_path(std::string module_name, std::string file_name); IMP_END_INTERNAL_NAMESPACE %(PREPROC)s_BEGIN_NAMESPACE %(PREPROC)sEXPORT const VersionInfo& get_module_version_info(); inline std::string get_module_name() { return "%(namespace)s"; } //! Return the path to installed data for this module /** Each module has its own data directory, so be sure to use the version of this function in the correct module. To read the data file "data_library" that was placed in the \c data directory of module "mymodule", do something like \code std::ifstream in(IMP::mymodule::get_data_path("data_library")); \endcode This will ensure that the code works when \imp is installed or used via the \c tools/imppy.sh script. */ inline std::string get_data_path(std::string file_name) { return IMP::internal::get_data_path("%(module)s", file_name); } //! Return the path to installed example data for this module /** Each module has its own example directory, so be sure to use the version of this function in the correct module. For example to read the file \c example_protein.pdb located in the \c examples directory of the IMP::atom module, do \code IMP::atom::read_pdb(IMP::atom::get_example_path("example_protein.pdb", model)); \endcode This will ensure that the code works when \imp is installed or used via the \c tools/imppy.sh script. */ inline std::string get_example_path(std::string file_name) { return IMP::internal::get_example_path("%(module)s", file_name); } %(PREPROC)s_END_NAMESPACE #endif // SWIG #endif /* %(PREPROC)s_CONFIG_H */""" % vars def _print_config_h(target, source, env): vars= imp_module.make_vars(env) print "Generating %(module)s_config.h"%vars ConfigH = Builder(action=Action(_action_config_h, _print_config_h)) def _action_config_cpp(target, source, env): vars= imp_module.make_vars(env) cpp = file(target[0].abspath, 'w') print >> cpp, """/** * \\file %(module_include_path)s/config.cpp * \\brief %(module)s module version information. * * Copyright 2007-2010 IMP Inventors. All rights reserved. * */ """ % vars print >> cpp, """#include <%(module_include_path)s/%(module)s_config.h> #include """ % vars print >> cpp, "%(PREPROC)s_BEGIN_NAMESPACE\n" % vars print >> cpp, """ const VersionInfo& get_module_version_info() { static VersionInfo vi("%(module)s", "%(version)s"); return vi; } """ \ %vars print >> cpp, "\n%(PREPROC)s_END_NAMESPACE" % vars def _print_config_cpp(target, source, env): vars= imp_module.make_vars(env) print "Generating %(module)s_config.cpp"%vars ConfigCPP = Builder(action=Action(_action_config_cpp, _print_config_cpp))