35#include "CellMLToSharedLibraryConverter.hpp"
44#include <boost/foreach.hpp>
48#include "Warnings.hpp"
51#include "DynamicModelLoaderRegistry.hpp"
52#include "GetCurrentWorkingDirectory.hpp"
54#define IGNORE_EXCEPTIONS(code) \
69 std::string component)
70 : mPreserveGeneratedSources(preserveGeneratedSources),
71 mComponentName(component)
78 DynamicCellModelLoaderPtr p_loader;
81 size_t dot_position = absolute_path.find_last_of(
".");
82 if (dot_position == std::string::npos || absolute_path[dot_position+1] ==
'/')
85 EXCEPTION(
"File does not have an extension: " + absolute_path);
87 std::string extension = absolute_path.substr(dot_position+1);
92 if (extension ==
"so")
94 WARN_ONCE_ONLY(
"CellMLToSharedLibraryConverter asked to load a \".so\" file. On this architecture it should be \".dylib\"");
96 absolute_path.replace(dot_position+1, 5, extension);
101 if (!file_path_copy.
Exists())
103 EXCEPTION(
"Dynamically loadable cell model '" + absolute_path +
"' does not exist.");
105 if (extension ==
"cellml")
108 size_t slash_position = absolute_path.find_last_of(
"/\\");
109 assert(slash_position != std::string::npos);
110 std::string folder = absolute_path.substr(0, slash_position+1);
111 std::string leaf = absolute_path.substr(slash_position+1, dot_position-slash_position);
112 std::string so_path = folder +
"lib" + leaf +
msSoSuffix;
119 EXCEPTION(
"Unable to convert .cellml to .so unless called collectively, due to possible race conditions.");
134 EXCEPTION(
"Unsupported extension '." + extension +
"' of file '" + absolute_path +
"'; must be .so, .dylib or .cellml");
141 const std::string& rCellmlFolder)
146 std::string old_cwd = GetCurrentWorkingDirectory();
151 if (!chaste_root.
IsDir())
154 <<
"' - you need the source to use CellML models directly in Chaste.");
157 if (!component_dir.
IsDir())
169 std::stringstream folder_name;
170 folder_name <<
"dynamic/tmp_" << getpid() <<
"_" << time(NULL);
192 std::vector<FileFinder> cellml_files = cellml_folder.
FindMatches(cellml_leaf_name +
"*");
194 BOOST_FOREACH(
const FileFinder& r_cellml_file, cellml_files)
196 r_cellml_file.
CopyTo(tmp_folder);
199 std::string cmake_lists_filename = tmp_folder.
GetAbsolutePath() +
"/CMakeLists.txt";
200 std::ofstream cmake_lists_filestream(cmake_lists_filename.c_str());
201 cmake_lists_filestream <<
"cmake_minimum_required(VERSION 3.16.3)\n" <<
202 "set(CMAKE_CXX_STANDARD 17)\n" <<
203 "set(CMAKE_CXX_STANDARD_REQUIRED ON)\n" <<
204 "set(CMAKE_CXX_EXTENSIONS OFF)\n" <<
205 "project (ChasteCellMLToSharedLibraryConverter)\n" <<
206 "find_package(Python3 3.5 REQUIRED)\n" <<
207 "set(codegen_python3_venv " + chaste_root.
GetAbsolutePath() +
"/codegen_python3_venv/bin)\n" <<
210 "set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})\n" <<
211 "include_directories(${Chaste_THIRD_PARTY_INCLUDE_DIRS} ${Chaste_INCLUDE_DIRS})\n" <<
212 "add_library(" << cellml_leaf_name <<
" SHARED " <<
"${sources})\n" <<
213 "if (${CMAKE_SYSTEM_NAME} MATCHES \"Darwin\")\n" <<
214 " target_link_libraries(" << cellml_leaf_name <<
" \"-Wl,-undefined,dynamic_lookup\")\n" <<
216 "if (${CMAKE_CXX_COMPILER_ID} STREQUAL \"IntelLLVM\")\n" <<
217 " set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fp-model precise\")\n" <<
219 cmake_lists_filestream.close();
220 std::string cmake_args =
" -DCMAKE_PREFIX_PATH=" + chaste_root.
GetAbsolutePath() +
222 " -DChaste_ENABLE_TESTING=OFF" +
223 " -DBUILD_SHARED_LIBS=ON";
225 EXPECT0(system,
"cmake" + cmake_args +
" .");
236 so_file.
CopyTo(destination_folder);
259 EXCEPTION(
"Conversion of CellML to Chaste shared object failed. Error was: " + e.GetMessage());
268 std::stringstream args_stream;
269 copy(rArgs.begin(), rArgs.end(), std::ostream_iterator<std::string>(args_stream,
" "));
std::string ChasteBuildType()
std::string ChasteBuildDirName()
#define EXPECT0(cmd, arg)
#define IGNORE_RET(cmd, arg)
#define EXCEPTION(message)
#define EXCEPT_IF_NOT(test)
DynamicCellModelLoaderPtr Convert(const FileFinder &rFilePath, bool isCollective=true)
bool mPreserveGeneratedSources
CellMLToSharedLibraryConverter(bool preserveGeneratedSources=false, std::string component="heart")
void SetOptions(const std::vector< std::string > &rArgs)
void ConvertCellmlToSo(const std::string &rCellmlFullPath, const std::string &rCellmlFolder)
static const std::string msSoSuffix
std::string mComponentName
DynamicCellModelLoaderPtr GetLoader(const std::string &rPath)
static DynamicModelLoaderRegistry * Instance()
std::string GetLeafNameNoExtension() const
bool IsNewerThan(const FileFinder &rOtherEntity) const
std::string GetAbsolutePath() const
void DangerousRemove() const
std::vector< FileFinder > FindMatches(const std::string &rPattern) const
FileFinder GetParent() const
virtual void SetPath(const std::string &rPath, RelativeTo::Value relativeTo)
FileFinder CopyTo(const FileFinder &rDest) const