2010-10-01 19 views
17

La documentación de Octave sobre este tema es a la vez intimidante y escasa.¿Cómo puedo crear un distribuible Octave simple sin instalar Octave

No sabía dónde más para documentar la solución que encontré, así que estoy publicando aquí. Me disculpo si eso es inapropiado, pero quiero ayudar al siguiente tipo.

La siguiente solución es para una distribución simple de Windows.

Caso de uso:
Una solución se desarrolla en Octave 3.2.4, y necesita ser distribuido a con pocos conocimientos de informática los usuarios finales. Instalar y explicar Octave es imposible, la solución debe ser "con un solo clic" o "con muerte cerebral simple".

Problemas conocidos:
imread falla en 3.2.4 ya file_in_path.m está mal. Usted tendrá que actualizar el archivo file_in_path.m a la siguiente (simplemente reemplazarlo):

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=[]; 
+7

Está bien para responder a su propia pregunta, pero podría ser mejor para editar su pregunta, quitar la parte "solución", y que lo ponga por separado más adelante como una respuesta . De esa forma, si otras personas responden con sus propias respuestas, pueden competir en pie de igualdad, con la mejor respuesta flotando hasta la cima del orden de clasificación. –

+0

¿Estaría bien hacerlo ahora? No conozco la etiqueta aquí. Siempre he encontrado que este sitio es tan útil ... Quería ayudar al siguiente tipo. – Noah

+0

Sí, deberías hacer eso. – Radu

Respuesta

9

Solución: Crear un EXE distribuibles utilizando mkoctfile y empaquetar este exe con los archivos principales de octava, y otra .oct y .m archivos según sea necesario.

Paso 1: Cree un ejecutable independiente.

Se puede ver el código que funciona aquí: http://www.gnu.org/software/octave/doc/interpreter/Standalone-Programs.html

Particularmente el archivo "embedded.cc".

He simplificado ese archivo de la siguiente manera:

#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; 
} 

construir este archivo con el comando

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

Puede lanzar advertencias, pero siempre y cuando se lanza ningún error, que debe estar bien . El archivo embedded.exe se compilará y se puede ejecutar. El único problema es que carecerá de todas las cosas buenas que hacen que octava sea increíble. Tendrás que proporcionar esos.

Paso 2: Crear una carpeta de distribución

Usted tendrá que crear una copia de muchos de los archivos de octava. Sugiero un directorio específicamente para esto. Como mínimo, necesitará una copia de todas o la mayoría de las DLL en \ bin. Además, coloque su ejecutable distribuible en este directorio.

Paso 3: Otros archivos golpe-a-mole

Ahora tendrá que averiguar lo que serán necesarios otros archivos para ejecutar la secuencia de comandos .m. Puede simplificar este paso copiando \ oct \ i686-pc-mingw32 * .oct y \ share \ octave \ 3.2.4 \ m \ * \ *. M en el directorio de distribución, aunque esto será excesivo, y en realidad no lo hará prevenir el paso de golpear a un topo.

Ahora, debes jugar whack-a-mole o la tradición consagrada de "donde mi incluye estar en, yo?"

  1. Abra una línea de cmd y navegue a la carpeta de distribución.
  2. deshacerse de cualquier cadena camino útil. Sus clientes no tendrán ellos.
  3. intenta ejecutar el programa de embedded.exe. usted obtiene un error como el siguiente:..

    embedded.exe
    error: `max' undefined near line 83 column 22
    error: evaluating argument list element number 1
    error: evaluating argument list element number 1
    error: called from:
    error: T:\sms\Development\research\c2\disttest\strcat.m at line 83, column 3
    error: T:\sms\Development\research\c2\disttest\file_in_path.m at line 5, column 10
    error: T:\sms\Development\research\c2\disttest\imread.m at line 50, column 6

  4. un Buscar en la instalación de Octave para "max" va a ser un .oct o un archivo .m en este caso, es a .o archivo ct, max.oct. Cópialo en tu directorio de distribución.

    B Busca algo obvio como "min" y no obtiene ningún resultado. Esto se debe a que la función cargable "min" está en el archivo .oct "max.oct". Haga una copia de max.oct y cambie el nombre a min.oct. Funcionará ahora. ¿Cómo sabes dónde están las funciones? No estoy seguro. La mayoría de ellos se encuentran en lugares obvios como "max.oct" para min, y "fft2.oct" para "ifft2.oct". Buena suerte con todo eso.

  5. Repita hasta que se ejecute su ejecutable.

+4

Sin embargo, tenga en cuenta que si hace esto, su código debe ser liberado bajo una licencia compatible con GPL ya que Octave mismo es GPLv3 + y usted está vinculando su código a él. De sus preguntas frecuentes en (http://wiki.octave.org/FAQ#If_I_write_code_using_Octave_do_I_have_to_release_it_under_the_GPL.3F) "El código escrito utilizando la interfaz nativa de plug-in de Octave (también conocido como un archivo .oct) necesariamente se vincula con Octave Internal y se considera un derivado trabajo de Octave y, por lo tanto, debe ser lanzado bajo términos que sean compatibles con la GPL " – carandraug

4

Sólo para añadir que si desea ejecutar una secuencia de comandos en lugar de una función de m, entonces la línea de la embedded.cc:

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

debería ser:

octave_value_list out = feval ("your_custom_m_script"); 

También use 'which' para encontrar donde están empacadas las funciones faltantes. Por ejemplo para la función min:

octave:22> which min 

min es una función del archivo C: \ Octave \ Octave3.6.2_gcc4.6.2 \ lib \ octava \ 3.6.2 \ octubre \ i686-pc-mingw32 \ max .oct

1

Algo que encontré al vincular mi archivo m personalizado en una octava independiente:

  1. necesario #include <octave/toplev.h>
  2. Reemplazar return 0; (como antes) con clean_up_and_exit(0);

Sin estos pasos, mi programa se bloqueó repetidamente al salir.

1

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

de la solución de octava y no desde un archivo por lotes.

Sólo se salvaron de medio día (-;

1

En la solución anterior en la viñeta 4 B:

B You search for something obvious like "min", and get no results. This is because the Loadable Function "min" is in the .oct file "max.oct". Make a copy of max.oct, and rename it to min.oct. It will work now.

Esto no podría funcionar si alguna función que se está llamando desde function.m @folder y también para evitar la duplicación de archivos innecesarios, sólo tiene que añadir el siguiente código en algún lugar de su archivo m fuera @folder

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

Del mismo modo, se puede eliminar a través de

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

Asegúrese de que la ruta a max.oct se proporciona aquí.

La comprensión anterior se basa en un archivo PKG_ADD y PKG_DEL en el paquete de comunicaciones ubicado en \ Octave-4.0.1 \ lib \ octave \ packages \ communications-1.2.1 \ i686-w64-mingw32-api-v50 + \

0

Tenía ese mismo requisito (un clic, cerebro-muerto-simple), así que hice una configuración que contenía solamente curl.exe, el archivo por lotes a continuación, un exe que era un .bat disfrazado (simplemente llamando al archivo por lotes a continuación) y el script .vbs a continuación (no escrito por mí). Y por supuesto mi m-file.

Esto descargará Octave 4.2.1 como un programa portátil (32 bits, de lo contrario tendremos que volver a descargar si el sistema resulta ser de 32 bits), descomprimimos usando el script vbs, movemos el contenido al mismo carpeta como el archivo por lotes y ejecutarlo en modo GUI. Cada vez que se llame al mismo script, solo comprobará si octave.bat todavía está allí.

Por supuesto, esto resulta en una gran pérdida de espacio en el disco, descargando el zip de 280MB, que descomprime a más de 1GB (lo cual empeoraré al no eliminar el zip), y se queda con una ventana de cmd que no es fácil de esconder

Pero ofrece la solución más simple que pude encontrar. También es menos probable que se rompa en el futuro (ya sea con una actualización propia o una actualización de Octave). Algún día glorioso, mkoktfile será realmente fácil de usar y resolverá las dependencias por sí mismo, pero hasta ese día esta sigue siendo la solución que menos dolor de cabeza puedo encontrar. Y las aspirinas son más caras que el espacio en disco de otra persona.

::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 

Y j_unzip.vbs

' j_unzip.vbs 
' 
' UnZip a file script 
' 
' By Justin Godden 2010 
' 
' It's 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.") 
Cuestiones relacionadas