Skip to content

Commit

Permalink
Add function to distinguish shared vs static linking at runtime
Browse files Browse the repository at this point in the history
This is important because extensions can only be loaded correctly when
Cantera is linked as a shared library.
  • Loading branch information
speth authored and ischoegl committed Feb 3, 2023
1 parent 36ccb1b commit 57a9578
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 3 deletions.
5 changes: 5 additions & 0 deletions include/cantera/base/global.h
Expand Up @@ -87,6 +87,11 @@ void loadExtension(const std::string& extType, const std::string& name);
//! @since New in Cantera 3.0
void loadExtensions(const AnyMap& node);

//! Returns `true` if Cantera was loaded as a shared library in the current
//! application. Returns `false` if it was statically linked.
//! @since New in Cantera 3.0
bool usingSharedLibrary();

//! Delete and free all memory associated with the application
/*!
* Delete all global data. It should be called at the end of the
Expand Down
10 changes: 7 additions & 3 deletions src/SConscript
Expand Up @@ -41,6 +41,7 @@ libs = [('base', ['cpp'], baseSetup),
localenv = env.Clone()
localenv.Prepend(CPPPATH=[Dir('#include'), Dir('#include/cantera/ext'), Dir('.')])
localenv.Append(CCFLAGS=env['warning_flags'])
indicatorEnv = localenv.Clone() # Get this before any of the PCH complications

if env['CC'] == 'cl' and env['debug']:
env['use_pch'] = False # PCH doesn't work with per-file PDB
Expand Down Expand Up @@ -113,7 +114,8 @@ if env["python_package"] == "full":


# build the Cantera static library
lib = build(localenv.StaticLibrary('../lib/cantera', libraryTargets,
staticIndicator = indicatorEnv.SharedObject('extensions/canteraStatic.cpp')
lib = build(localenv.StaticLibrary('../lib/cantera', libraryTargets + staticIndicator,
SPAWN=get_spawn(localenv)))
localenv.Depends(lib, localenv['config_h_target'])
install('$inst_libdir', lib)
Expand Down Expand Up @@ -154,6 +156,8 @@ if localenv['layout'] != 'debian':
else:
sharedName = '../lib/cantera'

sharedIndicator = indicatorEnv.SharedObject('extensions/canteraShared.cpp')

if env['CC'] == 'cl':
# For MSVC, use the static library to create a .def file listing all
# symbols to export in the shared library.
Expand All @@ -164,12 +168,12 @@ if localenv['layout'] != 'debian':
'/IGNORE:4102'])

if localenv['versioned_shared_library']:
lib = build(localenv.SharedLibrary(sharedName, libraryTargets,
lib = build(localenv.SharedLibrary(sharedName, libraryTargets + sharedIndicator,
SPAWN=get_spawn(localenv),
SHLIBVERSION=localenv['cantera_pure_version']))
install(localenv.InstallVersionedLib, '$inst_libdir', lib)
else:
lib = build(localenv.SharedLibrary(sharedName, libraryTargets,
lib = build(localenv.SharedLibrary(sharedName, libraryTargets + sharedIndicator,
SPAWN=get_spawn(localenv)))
install('$inst_libdir', lib)

Expand Down
5 changes: 5 additions & 0 deletions src/base/application.cpp
Expand Up @@ -402,6 +402,11 @@ std::string Application::findInputFile(const std::string& name)

void Application::loadExtension(const string& extType, const string& name)
{
if (!usingSharedLibrary()) {
throw CanteraError("Application::loadExtension",
"Loading extensions requires linking to the Cantera shared library\n"
"rather than the static library");
}
if (m_loaded_extensions.count({extType, name})) {
return;
}
Expand Down
18 changes: 18 additions & 0 deletions src/extensions/canteraShared.cpp
@@ -0,0 +1,18 @@
//! @file canteraShared.cpp

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#include "cantera/base/ct_defs.h"

namespace Cantera
{

bool usingSharedLibrary()
{
// This implementation of usingSharedLibrary is compiled and embedded
// only in the Cantera shared library
return true;
}

}
18 changes: 18 additions & 0 deletions src/extensions/canteraStatic.cpp
@@ -0,0 +1,18 @@
//! @file canteraStatic.cpp

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#include "cantera/base/ct_defs.h"

namespace Cantera
{

bool usingSharedLibrary()
{
// This implementation of usingSharedLibrary is compiled and embedded
// only in the Cantera static library
return false;
}

}

0 comments on commit 57a9578

Please sign in to comment.