Beispiel #1
0
void PetscSetupUtils::CommonSetup()
{
    InitialisePetsc();

    // Check that the working directory is correct, or many tests will fail
    std::string cwd = GetCurrentWorkingDirectory() + "/";
    if (strcmp(cwd.c_str(), ChasteBuildRootDir()) != 0)
    {
#define COVERAGE_IGNORE
        // Change directory
        std::cout << std::endl << "Changing directory from '" << cwd << "' to '" << ChasteBuildRootDir() << "'." << std::endl;
        EXPECT0(chdir, ChasteBuildRootDir());
        std::cout << "CWD now: " << GetCurrentWorkingDirectory() << std::endl;
#undef COVERAGE_IGNORE
    }

#ifdef TEST_FOR_FPE
    // Give all PETSc enabled tests the ability to trap for divide-by-zero
    feenableexcept(FE_DIVBYZERO | FE_INVALID );
    // Catch all SIGFPE signals and convert them to exceptions (before PETSc gets to them)
    struct sigaction sa;
    sa.sa_sigaction = FpeSignalToAbort;
    sa.sa_flags = SA_RESETHAND|SA_SIGINFO;
    sa.sa_restorer = 0;
    sigaction(SIGFPE, &sa, NULL);
#endif
}
void CellMLToSharedLibraryConverter::ConvertCellmlToSo(const std::string& rCellmlFullPath,
                                                       const std::string& rCellmlFolder)
{
    FileFinder tmp_folder;
    FileFinder build_folder;

    std::string old_cwd = GetCurrentWorkingDirectory();
    // Check that the Chaste build tree exists
    FileFinder chaste_root("", RelativeTo::ChasteBuildRoot);

    if (!chaste_root.IsDir())
    {
        EXCEPTION("No Chaste build tree found at '" << chaste_root.GetAbsolutePath()
                  << "' - you need the source to use CellML models directly in Chaste.");
    }
    FileFinder component_dir(mComponentName, RelativeTo::ChasteBuildRoot);
    if (!component_dir.IsDir())
    {
        EXCEPTION("Unable to convert CellML model: required Chaste component '" << mComponentName
                  << "' does not exist in '" << chaste_root.GetAbsolutePath() << "'.");
    }
    // Try the conversion
    try
    {
        // Need to create a .so file from the CellML...
        if (PetscTools::AmMaster())
        {
            // Create a temporary folder within heart/dynamic
            std::stringstream folder_name;
            folder_name << "dynamic/tmp_" << getpid() << "_" << time(NULL);

#ifdef CHASTE_CMAKE ///todo: #2656 - ignoring all cmake-specific code, revise after cmake transition
#define COVERAGE_IGNORE
            tmp_folder.SetPath(component_dir.GetAbsolutePath() + "/" + folder_name.str(), RelativeTo::Absolute);
            build_folder.SetPath(component_dir.GetAbsolutePath() + "/" + folder_name.str(), RelativeTo::Absolute);
#undef COVERAGE_IGNORE
#else
            tmp_folder.SetPath(component_dir.GetAbsolutePath() + "/" + folder_name.str(), RelativeTo::Absolute);
            build_folder.SetPath(component_dir.GetAbsolutePath() + "/build/" + ChasteBuildDirName() + "/" + folder_name.str(), RelativeTo::Absolute);
#endif

            int ret = mkdir((tmp_folder.GetAbsolutePath()).c_str(), 0700);
            if (ret != 0)
            {
                EXCEPTION("Failed to create temporary folder '" << tmp_folder.GetAbsolutePath() << "' for CellML conversion: "
                          << strerror(errno));
            }

            // Copy the .cellml file (and any relevant others) into the temporary folder
            FileFinder cellml_file(rCellmlFullPath, RelativeTo::Absolute);
            FileFinder cellml_folder = cellml_file.GetParent();
            std::string cellml_leaf_name = cellml_file.GetLeafNameNoExtension();
            std::vector<FileFinder> cellml_files = cellml_folder.FindMatches(cellml_leaf_name + "*");

            BOOST_FOREACH(const FileFinder& r_cellml_file, cellml_files)
            {
                r_cellml_file.CopyTo(tmp_folder);
            }

#ifdef CHASTE_CMAKE ///todo: #2656 - ignoring all cmake-specific code, revise after cmake transition
#define COVERAGE_IGNORE
            std::string cmake_lists_filename = tmp_folder.GetAbsolutePath() + "/CMakeLists.txt";
            std::ofstream cmake_lists_filestream(cmake_lists_filename.c_str());
            cmake_lists_filestream << "cmake_minimum_required(VERSION 2.8.10)\n" <<
                                      "find_package(Chaste COMPONENTS " << mComponentName << ")\n" <<
                                      "chaste_do_cellml(sources " << cellml_file.GetAbsolutePath() << " " << "ON)\n" <<
                                      "set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})\n" <<
                                      "include_directories(${Chaste_THIRD_PARTY_INCLUDE_DIRS} ${Chaste_INCLUDE_DIRS})\n" <<
                                      "add_library(" << cellml_leaf_name << " SHARED " << "${sources})\n"
                                      //"target_link_libraries(" << cellml_leaf_name << " ${Chaste_LIBRARIES})\n"
                                      ;
            cmake_lists_filestream.close();
            std::string cmake_args = " -DCMAKE_PREFIX_PATH=" + chaste_root.GetAbsolutePath() +
                                     " -DCMAKE_BUILD_TYPE=" + ChasteBuildType() +
                                     " -DBUILD_SHARED_LIBS=ON" +
                                     " -DENABLE_CHASTE_TESTING=OFF" +
                                     " -DChaste_USE_SHARED_LIBS=ON";
            EXPECT0(chdir, tmp_folder.GetAbsolutePath());
            EXPECT0(system, "cmake" + cmake_args + " .");
            EXPECT0(system, "cmake --build . --config " + ChasteBuildType());
#undef COVERAGE_IGNORE
#else
            // Change to Chaste source folder
            EXPECT0(chdir, chaste_root.GetAbsolutePath());
            // Run scons to generate C++ code and compile it to a .so
            EXPECT0(system, "scons --warn=no-all dyn_libs_only=1 build=" + ChasteBuildType() + " " + tmp_folder.GetAbsolutePath());
#endif

            FileFinder so_file(tmp_folder.GetAbsolutePath() + "/lib" + cellml_leaf_name + "." + msSoSuffix, RelativeTo::Absolute);
            EXCEPT_IF_NOT(so_file.Exists());
            // CD back
            EXPECT0(chdir, old_cwd);

            // Copy the .so to the same folder as the original .cellml file
            FileFinder destination_folder(rCellmlFolder, RelativeTo::Absolute);
            so_file.CopyTo(destination_folder);

            if (mPreserveGeneratedSources)
            {
                // Copy generated source code as well
                std::vector<FileFinder> generated_files = build_folder.FindMatches("*.?pp");
                BOOST_FOREACH(const FileFinder& r_generated_file, generated_files)
                {
                    r_generated_file.CopyTo(destination_folder);
                }
            }
            // Delete the temporary folders
            build_folder.DangerousRemove();
            tmp_folder.DangerousRemove();
        }