Подтвердить что ты не робот

Как создать простой Octave дистрибутив без установки Octave

Документация Octave по этому вопросу является одновременно устрашающей и разреженной.

Я не знал, где еще задокументировать решение, которое я нашел, поэтому я размещаю здесь. Прошу прощения, если это неуместно, но я хочу помочь следующему парню.

Следующее решение для простых распространяемых окон.

Пример использования:
Решение разработано в Octave 3.2.4 и должно быть распространено среди конечных пользователей с небольшим количеством навыков работы с компьютером. Установка и объяснение Octave невозможны, решение должно быть "одним щелчком" или "мертвым мозгом".

Известные проблемы:
imread не работает в 3.2.4, потому что file_in_path.m неверен. Вам нужно будет обновить файл file_in_path.m до следующего (просто замените его):

function name=file_in_path(p,file)
  idx=[1 findstr(p,pathsep) length(p)+1];
  for i=1:length(idx)-1
    if idx(i+1)-idx(i)<=1
      dir=strcat(pwd,"/");
    else
      dir=p(idx(i)+1:idx(i+1)-1);
    end
    name = fullfile(dir, file);
    fid = fopen(name,"r");
    if fid >= 0
      fclose(fid);
      return
    end
  end
  fid = fopen(file,"r");
  if fid >= 0,
    fclose(fid);
    name=file;
    return
  end
  name=[]; 
4b9b3361

Ответ 1

Создайте дистрибутивный exe с помощью mkoctfile и упакуйте этот exe с основными файлами Octave и другими файлами .oct и .m при необходимости.

Шаг 1. Создайте автономный исполняемый файл.

Вы можете увидеть код, который работает здесь: http://www.gnu.org/software/octave/doc/interpreter/Standalone-Programs.html

В частности, файл "embedded.cc".

Я упростил этот файл следующим образом:

#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>

int
main (int argc, char *argvc[])
{
  string_vector argv (2);
  argv(0) = "embedded";
  argv(1) = "-q";

  octave_main (2, argv.c_str_vec(), 1);

  octave_value_list in = octave_value (argvc[1]);
  octave_value_list out = feval ("your_custom_m_file", in);

  if (!error_state && out.length () > 0)
    {
    }
    else
    {
        std::cout << "invalid\n";
    }

  return 0;
}

Создайте этот файл с помощью команды

mkoctfile --link-stand-alone embedded.cc -o embedded

Он может вызывать предупреждения, но до тех пор, пока он не вызывает ошибок, вы должны быть в порядке. Файл embedded.exe будет создан и может быть запущен. Единственная проблема заключается в том, что ей не хватит всех лакомств, которые делают октаву удивительной. Вы должны будете предоставить их.

Шаг 2. Создайте папку распространения

Вам нужно будет создать копию многих файлов Octave. Я предлагаю каталог специально для этого. Как минимум, вам понадобится копия всех или большинства DLL в \bin. Кроме того, поместите ваш дистрибутивный исполняемый файл в этот каталог.

Шаг 3: Другие файлы whack-a-mole

Теперь вам нужно выяснить, какие другие файлы понадобятся для запуска вашего .m script. Вы можете упростить этот шаг, скопировав \oct\i686-pc-mingw32 *.oct и \share\octave\3.2.4\m\*\*. M в каталог распространения, хотя это будет излишним, и на самом деле это не будет предотвратите шаг ударов-моль.

Теперь вы должны сыграть в битку или послушную традицию "где мои включится, лет?"

  • Откройте приглашение cmd и перейдите в свою папку распространения.
  • Избавьтесь от любых полезных строк PATH. Ваши клиенты не будут иметь их.
  • Попытайтесь запустить программу embedded.exe. Появится сообщение об ошибке:

    embedded.exe
    ошибка: `max 'undefined рядом строка 83 столбец 22
    error: оценка элемента списка аргументов номер 1
    error: оценка элемента списка аргументов номер 1
    error: звонок из:
    ошибка: T:\sms\Development\research\c2\disttest\strcat.m в строке 83, столбец 3
    ошибка: T:\sms\Development\research\c2\disttest\file_in_path.m в строке 5, столбец 10
    ошибка: T:\sms\Development\research\c2\disttest\imread.m в строке 50, столбец 6

  • A Поиск в вашей установке Octave для "max". Это будет либо файл .oct, либо .m. В этом случае это файл .oct, max.oct. Скопируйте его в каталог распространения.

    B Вы ищете что-то очевидное, как "min", и не получаете никаких результатов. Это связано с тем, что загружаемая функция "мин" находится в .oct файле "max.oct". Сделайте копию max.oct и переименуйте ее в min.oct. Он будет работать сейчас. Откуда вы знаете, где находятся функции? Я не уверен. Большинство из них находятся в очевидных местах, таких как "max.oct" для min, и "fft2.oct" для "ifft2.oct". Удачи вам в этом.

  • Повторяйте до запуска исполняемого файла.

Ответ 2

Просто добавьте, что если вы хотите запустить script вместо функции m, тогда строка embedded.cc:

octave_value_list out = feval ("your_custom_m_file", in);

должен быть:

octave_value_list out = feval ("your_custom_m_script");

Также используйте 'which', чтобы найти, где упакованы недостающие функции. Например, для функции min:

octave:22> which min

min - это функция из файла C:\Octave\Octave3.6.2_gcc4.6.2\lib\octave\3.6.2\oct\i686-pc-mingw32\max.oct

Ответ 3

Что-то, что я обнаружил при связывании моего пользовательского файла m в автономном Octave:

  • Требуется #include <octave/toplev.h>
  • Замените return 0; (как указано выше) на clean_up_and_exit(0);

Без этих шагов моя программа несколько раз рушилась при выходе.

Ответ 4

Выполнить mkoctfile --link-stand-alone embedded.cc -o embedded

из октавного решения, а не из командного файла.

Только что спас вам полдня (-;

Ответ 5

В приведенном выше решении в пуле 4 B:

B Вы ищете что-то очевидное, как "min", и не получите никаких результатов. Это связано с тем, что загружаемая функция "min" находится в файле .oct "Max.oct". Сделайте копию max.oct и переименуйте ее в min.oct. Это будет работайте сейчас.

Это может не работать, если какая-либо функция вызывается из @folder function.m, а также во избежание ненужных дублированных файлов просто добавьте следующий код где-нибудь в ваш файл m за пределами @folder

autoload ("min", "max.oct");

Аналогично, его можно удалить с помощью

autoload ("min", "max.oct", "remove");

Убедитесь, что здесь указан путь к max.oct.

Вышеописанное понимание основано на файле PKG_ADD и PKG_DEL в пакете связи, расположенном по адресу \Octave-4.0.1\lib\octave\packages\communications-1.2.1\i686-w64-mingw32-api-v50 +\

Ответ 6

Посмотрите Strategyo Octave Compiler.

(Я еще не тестировал его, но планирую сделать это в ближайшие несколько дней.)

Ответ 7

У меня было такое же требование (один клик, простой в мозге), поэтому я создал установку, содержащую только curl.exe, пакетный файл ниже, exe, который был скрытым .bat(просто вызывающий пакетный файл ниже) и .vbs script ниже (не написано мной). И, конечно, мой m файл.

Это загрузит Octave 4.2.1 в качестве переносной программы (32 бит, в противном случае нам пришлось бы загружать снова, если система окажется 32 бит), распакуйте с помощью vbs script, переместите содержимое в той же папке, что и командный файл, и запускать ее в режиме графического интерфейса. Каждый раз, когда вызывается тот же самый script, он проверяет, остается ли octave.bat.

Конечно, это приводит к огромной трате дискового пространства, загружая 280 мегабайт ZIP, который распаковывается до более чем 1 ГБ (что я делаю еще хуже, не удаляя почтовый индекс потом), и вы застряли в CMD-окне, которое не легко скрыть.

Но он предлагает самое простое решение, которое я могу найти. Кроме того, он вряд ли будет разорван в будущем (либо с обновлением, либо с обновлением от Octave). Какой-то славный день, mkoktfile будет на самом деле прост в использовании и самостоятельно будет решать зависимости, но до этого дня это остается наименее вызывающим головную боль решением, которое я мог бы найти. А аспирины дороже, чем кто-то еще на диске.

::this file will test if the octave portable is downloaded and unpacked
@ECHO OFF

SET my_m_file=your_mfile.m
SET name_of_this_script=run_me.bat

::if the file exists, skip to the actual running.
IF EXIST "octave.bat" goto OctaveIsExtracted
IF EXIST "octave-4.2.1-w32.zip" goto OctaveIsDownloaded
ECHO The runtime (Octave portable 4.2.1) will now be downloaded.
ECHO This may take a long time, as it is about 280MB.
ECHO .
ECHO If this download restarts multiple times, you can manually download the octave-4.2.1-w32.zip from the GNU website. Make sure to unpack the contents.
::if this errors, you can uncomment the line with archive.org (which doesn't report total size during download)
curl http://ftp.gnu.org/gnu/octave/windows/octave-4.2.1-w32.zip > octave-4.2.1-w32.zip
::curl http://web.archive.org/web/20170827205614/https://ftp.gnu.org/gnu/octave/windows/octave-4.2.1-w32.zip > octave-4.2.1-w32.zip
:OctaveIsDownloaded
::check to see if the file size is the correct size to assume a successful download
::if the file size is incorrect, delete the file, restart this script to attempt a new download
::file size should be 293570269 bytes
call :filesize octave-4.2.1-w32.zip
IF /I "%size%" GEQ "293560000" goto OctaveIsDownloadedSuccessfully
del octave-4.2.1-w32.zip
::start new instance and exit and release this one
start %name_of_this_script%
exit
:OctaveIsDownloadedSuccessfully
IF EXIST "octave.bat" goto OctaveIsExtracted
::unzip and move those contents to the current folder
ECHO Unzipping octave portable, this may take a moment.
cscript //B j_unzip.vbs octave-4.2.1-w32.zip
SET src_folder=octave-4.2.1
SET tar_folder=%cd%
for /f %%a IN ('dir "%src_folder%" /b') do move %src_folder%\%%a %tar_folder%
pause
:OctaveIsExtracted
octave.bat %my_m_file%
goto :eof

:filesize
  set size=%~z1
  exit /b 0

И j_unzip.vbs

' j_unzip.vbs
'
' UnZip a file script
'
' By Justin Godden 2010
'
' It a mess, I know!!!
'

' Dim ArgObj, var1, var2
Set ArgObj = WScript.Arguments

If (Wscript.Arguments.Count > 0) Then
 var1 = ArgObj(0)
Else
 var1 = ""
End if

If var1 = "" then
 strFileZIP = "example.zip"
Else
 strFileZIP = var1
End if

'The location of the zip file.
REM Set WshShell = CreateObject("Wscript.Shell")
REM CurDir = WshShell.ExpandEnvironmentStrings("%%cd%%")
Dim sCurPath
sCurPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")
strZipFile = sCurPath & "\" & strFileZIP
'The folder the contents should be extracted to.
outFolder = sCurPath
'original line: outFolder = sCurPath & "\"

 WScript.Echo ( "Extracting file " & strFileZIP)

Set objShell = CreateObject( "Shell.Application" )
Set objSource = objShell.NameSpace(strZipFile).Items()
Set objTarget = objShell.NameSpace(outFolder)
intOptions = 256
objTarget.CopyHere objSource, intOptions

 WScript.Echo ( "Extracted." )