xref: /petsc/config/PETSc/options/sharedLibraries.py (revision 053abcdfeaa3c4bf7b7c01a7334c7edc5567db03)
1from __future__ import generators
2import config.base
3
4class Configure(config.base.Configure):
5  def __init__(self, framework):
6    config.base.Configure.__init__(self, framework)
7    self.headerPrefix = ''
8    self.substPrefix  = ''
9    self.useShared    = 0
10    return
11
12  def __str1__(self):
13    txt =  '  Single library: %s\n' % ('yes' if self.framework.argDB['with-single-library'] else 'no')
14    txt += '  Shared libraries: %s\n' % ('yes' if self.useShared else 'no')
15    return txt
16
17  def setupHelp(self, help):
18    import nargs
19    help.addArgument('PETSc', '-with-shared-libraries=<bool>', nargs.ArgBool(None, 1, 'Make PETSc libraries shared -- libpetsc.so (Unix/Linux) or libpetsc.dylib (Mac)'))
20    help.addArgument('PETSc', '-with-serialize-functions=<bool>', nargs.ArgBool(None, 0, 'Allows function pointers to be serialized to binary files with string representations'))
21    return
22
23  def setupDependencies(self, framework):
24    config.base.Configure.setupDependencies(self, framework)
25    self.arch         = framework.require('PETSc.options.arch', self)
26    self.debuggers    = framework.require('config.utilities.debuggers', self)
27    self.setCompilers = framework.require('config.setCompilers', self)
28    self.headers      = framework.require('config.headers', self)
29    self.functions    = framework.require('config.functions', self)
30    self.ftm          = framework.require('config.utilities.featureTestMacros', self)
31    return
32
33  def checkSharedDynamicPicOptions(self):
34    '''if user specified out-dated 'with-shared' or 'with-dynamic' - flag an error'''
35    if 'with-shared' in self.framework.argDB:
36      raise RuntimeError('Option "--with-shared" no longer exists. Use "--with-shared-libraries".')
37    if 'with-dynamic' in self.framework.argDB or 'with-dynamic-loading' in self.framework.argDB:
38      raise RuntimeError('Option "--with-dynamic" and "--with-dynamic-loading" no longer exist.')
39    if self.framework.argDB['with-shared-libraries'] and not self.framework.argDB['with-pic'] and 'with-pic' in self.framework.clArgDB:
40      raise RuntimeError('If you use --with-shared-libraries you cannot disable --with-pic')
41
42    # default with-shared-libraries=1 => --with-pic=1
43    # Note: there is code in setCompilers.py that uses this as default.
44    if self.framework.argDB['with-shared-libraries'] and not self.framework.argDB['with-pic']: self.framework.argDB['with-pic'] = 1
45    return
46
47
48  def configureSharedLibraries(self):
49    '''Checks whether shared libraries should be used, for which you must
50      - Specify --with-shared-libraries
51      - Have found a working shared linker
52    Defines PETSC_USE_SHARED_LIBRARIES if they are used'''
53    import sys
54
55    self.useShared = self.framework.argDB['with-shared-libraries'] and not self.setCompilers.staticLibraries
56
57    if self.useShared:
58      #if config.setCompilers.Configure.isSolaris(self.log) and config.setCompilers.Configure.isGNU(self.framework.getCompiler(),self.log):
59      #  self.addMakeRule('shared_arch','shared_'+self.arch.hostOsBase+'gnu')
60      #elif '-qmkshrobj' in self.setCompilers.sharedLibraryFlags:
61      #  self.addMakeRule('shared_arch','shared_linux_ibm')
62      #else:
63      #  self.addMakeRule('shared_arch','shared_'+self.arch.hostOsBase)
64
65      # Linux is the default
66      if self.setCompilers.isDarwin(self.log):
67        self.addMakeRule('shared_arch','shared_darwin')
68        self.addMakeMacro('SONAME_FUNCTION', '$(1).$(2).dylib')
69        self.addMakeMacro('SONAME_SFX_FUNCTION', '$(1)$(LIB_NAME_SUFFIX).$(2).dylib')
70        self.addMakeMacro('SL_LINKER_FUNCTION', '-dynamiclib -install_name $(call SONAME_FUNCTION,$(1),$(2)) -compatibility_version $(2) -current_version $(3) -undefined dynamic_lookup')
71      elif self.setCompilers.CC.find('win32fe') >=0:
72        self.addMakeMacro('SONAME_FUNCTION', '$(1).dll')
73        self.addMakeMacro('SONAME_SFX_FUNCTION', '$(1)$(LIB_NAME_SUFFIX).dll')
74        self.addMakeMacro('SL_LINKER_FUNCTION', '-LD')
75        self.addMakeMacro('PETSC_DLL_EXPORTS', '1')
76      else:
77        # TODO: check that -Wl,-soname,${LIBNAME}.${SL_LINKER_SUFFIX} can be passed (might fail on Intel)
78        # TODO: check whether we need to specify dependent libraries on the link line (long test)
79        self.addMakeRule('shared_arch','shared_linux')
80        self.addMakeMacro('SONAME_FUNCTION', '$(1).$(SL_LINKER_SUFFIX).$(2)')
81        self.addMakeMacro('SONAME_SFX_FUNCTION', '$(1)$(LIB_NAME_SUFFIX).$(SL_LINKER_SUFFIX).$(2)')
82        self.addMakeMacro('SL_LINKER_FUNCTION', self.framework.getSharedLinkerFlags() + ' -Wl,-soname,$(call SONAME_FUNCTION,$(notdir $(1)),$(2))')
83        if config.setCompilers.Configure.isMINGW(self.framework.getCompiler(),self.log):
84          self.addMakeMacro('PETSC_DLL_EXPORTS', '1')
85      self.addMakeMacro('BUILDSHAREDLIB','yes')
86    else:
87      self.addMakeRule('shared_arch','')
88      self.addMakeMacro('BUILDSHAREDLIB','no')
89    if self.useShared:
90      self.addDefine('USE_SHARED_LIBRARIES', 1)
91    else:
92      self.logPrint('Shared libraries - disabled')
93    return
94
95  def configureDynamicLibraries(self):
96    '''Checks whether dynamic loading is available (with dlfcn.h and libdl)'''
97    if self.setCompilers.dynamicLibraries:
98      self.addDefine('HAVE_DYNAMIC_LIBRARIES', 1)
99    return
100
101  def configureSerializedFunctions(self):
102    '''
103    Defines PETSC_SERIALIZE_FUNCTIONS if they are used
104    Requires shared libraries'''
105    import sys
106
107    if self.framework.argDB['with-serialize-functions'] and self.setCompilers.dynamicLibraries:
108      self.addDefine('SERIALIZE_FUNCTIONS', 1)
109
110  def checkSymbolResolution(self):
111    '''Checks that dladdr() works'''
112    if self.headers.haveHeader('dlfcn.h') and self.functions.haveFunction('dlerror'):
113      ftm = ''
114      if self.ftm.defines.get('_GNU_SOURCE'): ftm = '#define _GNU_SOURCE\n'
115      if self.checkCompile('%s#include<stdlib.h>\n#include <dlfcn.h>\n' % ftm, 'Dl_info info;\nif (dladdr(*(void **)&exit, &info) == 0) return 1;\n'):
116        self.addDefine('HAVE_DLADDR', 1)
117        if hasattr(self.headers.setCompilers, 'CXX'):
118          self.headers.pushLanguage('C++')
119          self.headers.check('cxxabi.h')
120          self.headers.popLanguage()
121
122  def configure(self):
123    self.executeTest(self.checkSharedDynamicPicOptions)
124    self.executeTest(self.configureSharedLibraries)
125    self.executeTest(self.configureDynamicLibraries)
126    self.executeTest(self.configureSerializedFunctions)
127    self.executeTest(self.checkSymbolResolution)
128    return
129