36 #include "CellMLToSharedLibraryConverter.hpp"
45 #include <boost/foreach.hpp>
49 #include "Warnings.hpp"
52 #include "DynamicModelLoaderRegistry.hpp"
53 #include "GetCurrentWorkingDirectory.hpp"
55 #define IGNORE_EXCEPTIONS(code) \
72 std::string component)
73 : mPreserveGeneratedSources(preserveGeneratedSources),
74 mComponentName(component)
81 DynamicCellModelLoaderPtr p_loader;
84 size_t dot_position = absolute_path.find_last_of(
".");
85 if (dot_position == std::string::npos)
87 EXCEPTION(
"File does not have an extension: " + absolute_path);
89 std::string extension = absolute_path.substr(dot_position+1);
94 if (extension ==
"so")
96 WARN_ONCE_ONLY(
"CellMLToSharedLibraryConverter asked to load a \".so\" file. On this architecture it should be \".dylib\"");
98 absolute_path.replace(dot_position+1, 5, extension);
103 if (!file_path_copy.
Exists())
105 EXCEPTION(
"Dynamically loadable cell model '" + absolute_path +
"' does not exist.");
107 if (extension ==
"cellml")
110 size_t slash_position = absolute_path.find_last_of(
"/\\");
111 assert(slash_position != std::string::npos);
112 std::string folder = absolute_path.substr(0, slash_position+1);
113 std::string leaf = absolute_path.substr(slash_position+1, dot_position-slash_position);
114 std::string so_path = folder +
"lib" + leaf +
msSoSuffix;
121 EXCEPTION(
"Unable to convert .cellml to .so unless called collectively, due to possible race conditions.");
136 EXCEPTION(
"Unsupported extension '." + extension +
"' of file '" + absolute_path +
"'; must be .so, .dylib or .cellml");
143 const std::string& rCellmlFolder)
148 std::string old_cwd = GetCurrentWorkingDirectory();
152 if (!chaste_root.
IsDir())
155 <<
"' - you need the source to use CellML models directly in Chaste.");
158 if (!component_dir.
IsDir())
170 std::stringstream folder_name;
171 folder_name <<
"dynamic/tmp_" << getpid() <<
"_" << time(NULL);
174 #define COVERAGE_IGNORE
177 #undef COVERAGE_IGNORE
194 std::vector<FileFinder> cellml_files = cellml_folder.
FindMatches(cellml_leaf_name +
"*");
196 BOOST_FOREACH(
const FileFinder& r_cellml_file, cellml_files)
198 r_cellml_file.
CopyTo(tmp_folder);
202 #define COVERAGE_IGNORE
203 std::string cmake_lists_filename = tmp_folder.
GetAbsolutePath() +
"/CMakeLists.txt";
204 std::ofstream cmake_lists_filestream(cmake_lists_filename.c_str());
205 cmake_lists_filestream <<
"cmake_minimum_required(VERSION 2.8.10)\n" <<
207 "chaste_do_cellml(sources " << cellml_file.
GetAbsolutePath() <<
" " <<
"ON)\n" <<
208 "set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})\n" <<
209 "include_directories(${Chaste_THIRD_PARTY_INCLUDE_DIRS} ${Chaste_INCLUDE_DIRS})\n" <<
210 "add_library(" << cellml_leaf_name <<
" SHARED " <<
"${sources})\n" <<
211 "if (${CMAKE_SYSTEM_NAME} MATCHES \"Darwin\")\n" <<
212 " target_link_libraries(" << cellml_leaf_name <<
" \"-Wl,-undefined,dynamic_lookup\")\n" <<
216 cmake_lists_filestream.close();
217 std::string cmake_args =
" -DCMAKE_PREFIX_PATH=" + chaste_root.
GetAbsolutePath() +
219 " -DChaste_ENABLE_TESTING=OFF" +
220 " -DBUILD_SHARED_LIBS=ON";
222 EXPECT0(system,
"cmake" + cmake_args +
" .");
224 #undef COVERAGE_IGNORE
239 so_file.CopyTo(destination_folder);
244 std::vector<FileFinder> generated_files = build_folder.
FindMatches(
"*.?pp");
245 BOOST_FOREACH(
const FileFinder& r_generated_file, generated_files)
247 r_generated_file.
CopyTo(destination_folder);
271 EXCEPTION(
"Conversion of CellML to Chaste shared object failed. Error was: " + e.
GetMessage());
279 const std::string& rModelName,
280 const std::vector<std::string>& rArgs,
281 const std::string& rExtraXml)
285 out_stream p_optfile = rHandler.
OpenOutputFile(rModelName +
"-conf.xml");
286 (*p_optfile) <<
"<?xml version='1.0'?>" << std::endl
287 <<
"<pycml_config>" << std::endl;
290 (*p_optfile) <<
"<command_line_args>" << std::endl;
291 for (
unsigned i=0; i<rArgs.size(); i++)
293 (*p_optfile) <<
"<arg>" << rArgs[i] <<
"</arg>" << std::endl;
295 (*p_optfile) <<
"</command_line_args>" << std::endl;
297 (*p_optfile) << rExtraXml <<
"</pycml_config>" << std::endl;
void DangerousRemove() const
static DynamicModelLoaderRegistry * Instance()
std::string ChasteBuildType()
std::string GetAbsolutePath() const
#define EXCEPTION(message)
FileFinder CopyTo(const FileFinder &rDest) const
#define EXPECT0(cmd, arg)
std::string ChasteBuildDirName()
DynamicCellModelLoaderPtr Convert(const FileFinder &rFilePath, bool isCollective=true)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
std::string GetMessage() const
CellMLToSharedLibraryConverter(bool preserveGeneratedSources=false, std::string component="heart")
DynamicCellModelLoaderPtr GetLoader(const std::string &rPath)
#define EXCEPT_IF_NOT(test)
std::vector< FileFinder > FindMatches(const std::string &rPattern) const
static const std::string msSoSuffix
bool mPreserveGeneratedSources
FileFinder GetParent() const
std::string GetLeafNameNoExtension() const
static void CreateOptionsFile(const OutputFileHandler &rHandler, const std::string &rModelName, const std::vector< std::string > &rArgs, const std::string &rExtraXml="")
void ConvertCellmlToSo(const std::string &rCellmlFullPath, const std::string &rCellmlFolder)
virtual void SetPath(const std::string &rPath, RelativeTo::Value relativeTo)
#define IGNORE_RET(cmd, arg)
std::string mComponentName
bool IsNewerThan(const FileFinder &rOtherEntity) const