Exemplo n.º 1
0
    def _make_model(self, log):
        """
        Compile the generated c-code into an executable
        """
        if os.name == 'nt':
            # Windows
            # Make model

            # add incremental build support for .c files
            makefile = open('{0}.makefile'.format(self.short_name)).read()
            makefile = makefile.replace('.PHONY: $(CFILES)', '# .PHONY: $(CFILES)')
            makefile = re.sub('^omc_main_target:', 'omc_main_target: {0}$(EXEEXT)\n{0}$(EXEEXT):'.format(self.short_name), makefile, flags=re.MULTILINE)
            makefile = makefile + """
%.o: %.c
\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -MMD -MP -MF $(<:.c=.d) $<
-include $(CFILES:.c=.d)
"""
            with open('Makefile'.format(self.short_name), 'wb') as makefile_out:
                makefile_out.write(makefile)

            # Add %OPENMODELICAHOME%\MinGW\bin to environment variables
            my_env = os.environ
            for path in (r'mingw\bin', # OpenModelica 1.9.1, 1.9.3
                    r'tools\msys\mingw32\bin',  # OpenModelica 1.11.0 32bit
                    r'tools\msys\mingw64\bin'):  # OpenModelica 1.11.0 64bit
                env_var_mingw = os.path.join(os.getenv('OPENMODELICAHOME'), path)
                # META-3623 make sure this path gets resolved first (prepend rather than append).
                my_env["PATH"] = env_var_mingw + os.pathsep + my_env["PATH"]
                log.debug('Added "{0}" to beginning of env var PATH.'.format(env_var_mingw))
            command = 'mingw32-make.exe -f Makefile omc_main_target'

            # compile the c-code
            t_stamp = time.time()
            try:
                subprocess_call(command, log, my_env)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp

        elif os.name == 'posix':
            # Unix
            # make -f model_name.makefile
            command = "make -f {0}.makefile".format(self.short_name)
            t_stamp = time.time()
            try:
                subprocess_call(command, log)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp
Exemplo n.º 2
0
    def _make_model(self, log):
        """
        Compile the generated c-code into an executable
        """
        if os.name == 'nt':
            # Windows
            # Make model

            # add incremental build support for .c files
            makefile = open('{0}.makefile'.format(self.short_name)).read()
            makefile = makefile.replace('.PHONY: $(CFILES)', '# .PHONY: $(CFILES)')
            makefile = re.sub('^omc_main_target:', 'omc_main_target: {0}$(EXEEXT)\n{0}$(EXEEXT):'.format(self.short_name), makefile, flags=re.MULTILINE)
            makefile = makefile + """
%.o: %.c
\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -MMD -MP -MF $(<:.c=.d) $<
-include $(CFILES:.c=.d)
"""
            with open('Makefile'.format(self.short_name), 'wb') as makefile_out:
                makefile_out.write(makefile)

            # Add %OPENMODELICAHOME%\MinGW\bin to environment variables
            env_var_mingw = os.path.join(os.getenv('OPENMODELICAHOME'), 'mingw', 'bin')
            my_env = os.environ
            # META-3623 make sure this path gets resolved first (prepend rather than append).
            my_env["PATH"] = env_var_mingw + os.pathsep + my_env["PATH"]
            log.debug('Added "{0}" to beginning of env var PATH.'.format(env_var_mingw))
            command = 'mingw32-make.exe -f Makefile omc_main_target'

            # compile the c-code
            t_stamp = time.time()
            try:
                subprocess_call(command, log, my_env)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp

        elif os.name == 'posix':
            # Unix
            # make -f model_name.makefile
            command = "make -f {0}.makefile".format(self.short_name)
            t_stamp = time.time()
            try:
                subprocess_call(command, log)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp
Exemplo n.º 3
0
    def _translate_modelica_model(self, log, my_env):
        """
        Call omc(.exe) to translate the modelica model into c-code.

        """
        os.chdir(self.mo_dir)

        command = '"{0}" +q +s "{1}"'.format(os.path.join(self.tool_path, 'omc'), self.mos_file_name)

        # only recompile if there is a .mo file newer than the _init.xml file
        latest_mtime = -1
        for root, dirs, files in os.walk('.'):
            for name in (f for f in files if f.endswith('.mo')):
                latest_mtime = max(os.stat(os.path.join(root, name)).st_mtime, latest_mtime)

        init_xml_name = os.path.join(self.mo_dir, self.short_name) + '_init.xml'

        if not os.path.isfile(init_xml_name) or os.stat(init_xml_name) < latest_mtime:
            t_stamp = time.time()
            try:
                return_string = subprocess_call(command, log, my_env)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError('OMC could not compile model.', sp_msg=err.returncode)
            self.translation_time = time.time() - t_stamp

            if os.path.exists(os.path.join(self.mo_dir, self.short_name) + '_init.xml'):
                self.model_is_compiled = True
            else:
                msg = 'Subprocess call with command = "{0}" returned with 0, but _init.xml does not '\
                      'exist - something went wrong during translation of model.'.format(command)
                raise ModelicaCompilationError(msg, return_string)
        else:
            self.model_is_compiled = True

        os.chdir(self.working_dir)
    def _generate_input_mat_file(self, log, my_env):
        """
        Generates an input file for dymosim(.exe) containing simulation settings

        """

        log.debug("Entered _generate_input_mat_file")

        self.input_mat = 'dsin.mat'

        # dymosim.exe -ib dsin.mat
        command = '{0} -ib {1}'.format(self.dymosim, self.input_mat)
        try:
            subprocess_call(command, log, my_env)
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Could not generate dsin.mat", sp_msg=err.returncode)
Exemplo n.º 5
0
    def _translate_modelica_model(self, log, my_env):
        """
        Call omc(.exe) to translate the modelica model into c-code.

        """
        os.chdir(self.mo_dir)

        command = '"{0}" +q +s --std=3.3 "{1}"'.format(os.path.join(self.tool_path, 'omc'), self.mos_file_name)

        # only recompile if there is a .mo file newer than the _init.xml file
        latest_mtime = -1
        for root, dirs, files in os.walk('.'):
            for name in (f for f in files if f.endswith('.mo')):
                latest_mtime = max(os.stat(os.path.join(root, name)).st_mtime, latest_mtime)

        init_xml_name = os.path.join(self.mo_dir, self.short_name) + '_init.xml'

        if not os.path.isfile(init_xml_name) or os.stat(init_xml_name) < latest_mtime:
            t_stamp = time.time()
            try:
                return_string = subprocess_call(command, log, my_env)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError('OMC could not compile model.', sp_msg=err.returncode)
            self.translation_time = time.time() - t_stamp

            if os.path.exists(os.path.join(self.mo_dir, self.short_name) + '_init.xml'):
                self.model_is_compiled = True
            else:
                msg = 'Subprocess call with command = "{0}" returned with 0, but _init.xml does not '\
                      'exist - something went wrong during translation of model.'.format(command)
                raise ModelicaCompilationError(msg, return_string)
        else:
            self.model_is_compiled = True

        os.chdir(self.working_dir)
Exemplo n.º 6
0
    def _generate_input_mat_file(self, log, my_env):
        """
        Generates an input file for dymosim(.exe) containing simulation settings

        """

        log.debug("Entered _generate_input_mat_file")

        self.input_mat = 'dsin.mat'

        # dymosim.exe -ib dsin.mat
        command = '{0} -ib {1}'.format(self.dymosim, self.input_mat)
        try:
            subprocess_call(command, log, my_env)
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Could not generate dsin.mat",
                                           sp_msg=err.returncode)
Exemplo n.º 7
0
    def simulate_model(self):
        """
        Simulate model using current settings

        """
        log = logging.getLogger()
        log.debug("Entered simulate_model")
        # create a .cmd file which will:
        #   1) run %JMODELICAHOME%\\setenv.bat and
        #   2) call a python script to simulate the model

        jmodelica_setenv_path = os.path.join(self.tool_path, 'setenv.bat')

        fmu_name = self.model_name.split('.')[-1] + '.fmu'

        with open(os.path.join('jmodelica_simulate.cmd'), 'wb') as file_out:
            lines = [r':: Use System Python (which should have access to JModelica) to compile the model',
                     r'echo off',
                     r'pushd %~dp0',
                     r'call {0}'.format(jmodelica_setenv_path),
                     r'"{0}" ..\scripts\jmodelica_simulate.py {1}'.format(self.system_python_path, fmu_name),
                     r'popd']
            file_out.write("\n".join(lines))
            
        # set up environment such that the libraries are included
        #my_env = os.environ
        #if self.lib_package_paths:
        #    my_env = self._setup_libs_env_vars()
        if os.path.isfile(self.simulate_failed_file):
            os.remove(self.simulate_failed_file)
        if os.path.isfile('j_simulate.log'):
            os.remove('j_simulate.log')
        t_start = time.time()
        try:
            return_string = subprocess_call(os.path.join('jmodelica_simulate.cmd'), log)
            log.debug(return_string)
            self.result_mat = self.model_name.replace('.', '_') + '_result.txt'
            if os.path.isfile(self.simulate_failed_file):
                raise ModelicaSimulationError("Simulation failed.")
        except subprocess.CalledProcessError as err:
            raise ModelicaSimulationError("Execution of jmodelica_simulate.cmd failed.", sp_msg=err.returncode)
        finally:
            if os.path.isfile('j_simulate.log'):
                with open('j_simulate.log', 'r') as f_in:
                    log.info('\n'.join(f_in.readlines()))

        self.simulation_time = time.time() - t_start
        self.total_time = self.compilation_time + self.simulation_time

        return self.model_did_simulate
Exemplo n.º 8
0
    def _make_model(self, log):
        """
        Compiles the generated c-code into an executable
        """
        if os.name == 'nt':
            # Windows
            # Make model

            # Add %OPENMODELICAHOME%\MinGW\bin to environment variables
            env_var_mingw = os.path.join(os.getenv('OPENMODELICAHOME'), 'mingw', 'bin')
            my_env = os.environ
            # META-3623 make sure this path gets resolved first (prepend rather than append).
            my_env["PATH"] = env_var_mingw + os.pathsep + my_env["PATH"]
            log.debug('Added "{0}" to beginning of env var PATH.'.format(env_var_mingw))
            command = 'mingw32-make.exe -f {0}.makefile'.format(self.short_name)

            # compile the c-code
            t_stamp = time.time()
            try:
                subprocess_call(command, log, my_env)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp

        elif os.name == 'posix':
            # Unix
            # make -f model_name.makefile
            command = "make -f {0}.makefile".format(self.short_name)
            t_stamp = time.time()
            try:
                subprocess_call(command, log)
            except subprocess.CalledProcessError as err:
                raise ModelicaCompilationError("Generated C-code from omc could not be compiled",
                                               sp_msg=err.returncode)
            self.make_time = time.time() - t_stamp
Exemplo n.º 9
0
    def _print_revision_number(self, log):
        """
        Gets the revision number of the omc-compiler

        """
        log.debug("Entered _print_revision_number")

        command = '"{0}" +version'.format(os.path.join(self.tool_path, "omc"))
        try:
            return_str = subprocess_call(command, log)
            version = return_str.split('(')
            self.tool_version = version[0].strip()
            self.tool_version_number = version[1].strip().strip(')')
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Could not call omc.", sp_msg=err.returncode)
Exemplo n.º 10
0
    def _translate_modelica_model(self, log, my_env):
        """
        Calls omc(.exe) to translate the modelica model into c-code.

        """
        os.chdir(self.mo_dir)

        command = '"{0}" +q +s "{1}"'.format(os.path.join(self.tool_path, 'omc'), self.mos_file_name)

        t_stamp = time.time()
        try:
            return_string = subprocess_call(command, log, my_env)
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError('OMC could not compile model.', sp_msg=err.returncode)
        self.translation_time = time.time() - t_stamp

        if os.path.exists(os.path.join(self.mo_dir, self.short_name) + '_init.xml'):
            self.model_is_compiled = True
        else:
            msg = 'Subprocess call with command = "{0}" returned with 0, but _init.xml does not '\
                  'exist - something went wrong during translation of model.'.format(command)
            raise ModelicaCompilationError(msg, return_string)

        # N.B. this is not used and thus not maintained
        if not self.working_dir == self.mo_dir:
            files_to_move = [self.short_name + '.c',
                             self.short_name + '.makefile',
                             self.short_name + '.o',
                             self.short_name + '_functions.c',
                             self.short_name + '_functions.h',
                             self.short_name + '_init.xml',
                             self.short_name + '_records.c',
                             self.short_name + '_records.o',
                             '_' + self.short_name + '.h']

            for this_file in files_to_move:
                dst_file_name = os.path.join(self.working_dir, this_file)
                if os.path.exists(dst_file_name):
                    # remove dst file if it already exists
                    os.remove(dst_file_name)
                this_file = os.path.join(self.mo_dir, this_file)
                if os.path.exists(this_file):
                    shutil.move(this_file, self.working_dir)

        os.chdir(self.working_dir)
Exemplo n.º 11
0
    def compile_model(self):
        """
        Compile the model

        """

        log = logging.getLogger()
        log.debug("Entered compile_model JModelica")

        # create a .cmd file which will:
        #   1) run %JMODELICAHOME%\\setenv.bat and
        #   2) call a python script to compile the model

        jmodelica_setenv_path = os.path.join(self.tool_path, 'setenv.bat')

        with open(os.path.join('jmodelica_compile.cmd'), 'wb') as file_out:
            lines = [r':: Use System Python (which should have access to JModelica) to compile the model',
                     r'echo off',
                     r'pushd %~dp0',
                     r'call {0}'.format(jmodelica_setenv_path),
                     r'"{0}" ..\scripts\jmodelica_compile.py {1}'.format(self.system_python_path, self.model_name),
                     r'popd']
            file_out.write("\n".join(lines))

        if os.path.isfile(self.compile_failed_file):
            os.remove(self.compile_failed_file)
        if os.path.isfile('j_compile.log'):
            os.remove('j_compile.log')

        t_start = time.time()
        try:
            return_string = subprocess_call(os.path.join('jmodelica_compile.cmd'), log)
            log.debug(return_string)
            if os.path.isfile(self.compile_failed_file):
                raise ModelicaCompilationError("Compilation failed.")
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Execution of jmodelica_compile.cmd failed.", sp_msg=err.returncode)        
        finally:
            if os.path.isfile('j_compile.log'):
                with open('j_compile.log', 'r') as f_in:
                    log.info('\n'.join(f_in.readlines()))

        self.compilation_time = time.time() - t_start
        return self.model_is_compiled
Exemplo n.º 12
0
    def _print_revision_number(self, log):
        """
        Get the revision number of the omc-compiler.
        """
        log.debug("Entered _print_revision_number")

        command = '"{0}" +version'.format(os.path.join(self.tool_path, "omc"))
        try:
            return_str = subprocess_call(command, log)
            version = return_str.split('(')
            self.tool_version = version[0].strip()
            if len(version) > 1:
                self.tool_version_number = version[1].strip().strip(')')
            else:
                # Around v.1.9.4 open-modelica changed version format string.
                # For example v1.9.4-dev-62-g0de2ae0 will now be under self.tool_version as is.
                self.tool_version_number = 'UNKNOWN'
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Could not call omc.", sp_msg=err.returncode)
Exemplo n.º 13
0
    def _print_revision_number(self, log):
        """
        Get the revision number of the omc-compiler.
        """
        log.debug("Entered _print_revision_number")

        command = '"{0}" +version'.format(os.path.join(self.tool_path, "omc"))
        try:
            return_str = subprocess_call(command, log)
            version = return_str.split('(')
            self.tool_version = version[0].strip()
            if len(version) > 1:
                self.tool_version_number = version[1].strip().strip(')')
            else:
                # Around v.1.9.4 open-modelica changed version format string.
                # For example v1.9.4-dev-62-g0de2ae0 will now be under self.tool_version as is.
                self.tool_version_number = 'UNKNOWN'
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Could not call omc.", sp_msg=err.returncode)
    def _translate_and_compile(self, log, my_env):
        """
        Translate modelica code into c-code and compile that
        code into executable

        """
        log.debug("Entered _translate_and_compile")
        os.chdir(self.mo_dir)

        command = ''
        if os.name == 'nt':
            command = '"{0}" /nowindow {1}'.format(os.path.join(self.tool_path, 'Dymola.exe'),
                                                   self.mos_file_name)
            my_env['PATH'] = my_env['PATH'].replace('"', '') # META-1507 Dymola may hang with a quote in the %PATH%
        elif os.name == 'posix':
            command = 'dymola /nowindow {0}'.format(self.mos_file_name)

        t_stamp = time.time()
        try:
            return_string = subprocess_call(command, log, my_env)
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError("Execution of the mos-script failed.", sp_msg=err.returncode)
        self.compilation_time = time.time() - t_stamp

        # setup name for executable
        if os.name == 'nt':
            self.dymosim = 'dymosim.exe'
        elif os.name == 'posix':
            self.dymosim = './dymosim'
            my_env.update({"LD_LIBRARY_PATH": "/opt/dymola/bin/lib"})

        try:
            with open('translationLog.txt', 'r') as f_in:
                translation_log = f_in.read()
        except IOError:
            translation_log = 'Warning, no translationLog.txt!'

        # make sure that dymosim(.exe) does exist
        if not os.path.exists(self.dymosim):
            msg = 'The sub process call with command "{0}" returned with 0, but {1} does not '\
                  'exist.'.format(command, self.dymosim)
            log.error(translation_log)
            raise ModelicaCompilationError(msg, sp_msg=return_string)

        log.info(translation_log)
        self.model_is_compiled = True
        #os.remove(self.mos_file_name)

        # N.B. this is not used and thus not maintained
        if not self.working_dir == self.mo_dir:
            files_to_move = ['buildlog.txt',
                             'dsfinal.txt',
                             'dsin.txt',
                             'dslog.txt',
                             'dsmodel.c',
                             'dymosim.exp',
                             'dymosim.lib',
                             'dymosim.exe',
                             'request',
                             'status']
            for this_file in files_to_move:
                dst_file_name = os.path.join(self.working_dir, this_file)
                if os.path.exists(dst_file_name):
                    # remove dst file if it already exists
                    os.remove(dst_file_name)

                this_file = os.path.join(self.mo_dir, this_file)
                if os.path.exists(this_file):
                    shutil.move(this_file, self.working_dir)

        os.chdir(self.working_dir)
Exemplo n.º 15
0
    def _translate_and_compile(self, log, my_env):
        """
        Translate modelica code into c-code and compile that
        code into executable

        """
        log.debug("Entered _translate_and_compile")
        os.chdir(self.mo_dir)

        command = ''
        if os.name == 'nt':
            command = '"{0}" /nowindow {1}'.format(
                os.path.join(self.tool_path, 'Dymola.exe'), self.mos_file_name)
            my_env['PATH'] = my_env['PATH'].replace(
                '"',
                '')  # META-1507 Dymola may hang with a quote in the %PATH%
        elif os.name == 'posix':
            command = 'dymola /nowindow {0}'.format(self.mos_file_name)

        t_stamp = time.time()
        try:
            return_string = subprocess_call(command, log, my_env)
        except subprocess.CalledProcessError as err:
            raise ModelicaCompilationError(
                "Execution of the mos-script failed.", sp_msg=err.returncode)
        self.compilation_time = time.time() - t_stamp

        # setup name for executable
        if os.name == 'nt':
            self.dymosim = 'dymosim.exe'
        elif os.name == 'posix':
            self.dymosim = './dymosim'
            my_env.update({"LD_LIBRARY_PATH": "/opt/dymola/bin/lib"})

        try:
            with open('translationLog.txt', 'r') as f_in:
                translation_log = f_in.read()
        except IOError:
            translation_log = 'Warning, no translationLog.txt!'

        # make sure that dymosim(.exe) does exist
        if not os.path.exists(self.dymosim):
            msg = 'The sub process call with command "{0}" returned with 0, but {1} does not '\
                  'exist.'.format(command, self.dymosim)
            log.error(translation_log)
            raise ModelicaCompilationError(msg, sp_msg=return_string)

        log.info(translation_log)
        self.model_is_compiled = True
        #os.remove(self.mos_file_name)

        # N.B. this is not used and thus not maintained
        if not self.working_dir == self.mo_dir:
            files_to_move = [
                'buildlog.txt', 'dsfinal.txt', 'dsin.txt', 'dslog.txt',
                'dsmodel.c', 'dymosim.exp', 'dymosim.lib', 'dymosim.exe',
                'request', 'status'
            ]
            for this_file in files_to_move:
                dst_file_name = os.path.join(self.working_dir, this_file)
                if os.path.exists(dst_file_name):
                    # remove dst file if it already exists
                    os.remove(dst_file_name)

                this_file = os.path.join(self.mo_dir, this_file)
                if os.path.exists(this_file):
                    shutil.move(this_file, self.working_dir)

        os.chdir(self.working_dir)