para - octave zip
¿Cómo creo un Octave simple distribuible sin instalar Octave? (7)
Algo que encontré al vincular mi archivo m personalizado en un Octave independiente:
- Se necesita
#include <octave/toplev.h>
- Reemplace la
return 0;
(como arriba) conclean_up_and_exit(0);
Sin estos pasos, mi programa se bloqueó repetidamente al salir.
La documentación de Octave sobre este tema es a la vez intimidante y dispersa.
No sabía dónde documentar la solución que encontré, así que estoy publicando aquí. Pido disculpas si eso es inapropiado, pero quiero ayudar al siguiente tipo.
La siguiente solución es para una simple ventana distribuible.
Caso de uso:
Una solución se desarrolla en Octave 3.2.4 y debe distribuirse a usuarios finales con pocas habilidades informáticas. Instalar y explicar Octave es imposible, la solución debe ser "de un solo clic" o "simple para el cerebro".
Problemas conocidos:
imread falla en 3.2.4 porque file_in_path.m es incorrecto. Necesitará actualizar el archivo file_in_path.m a lo 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=[];
Echa un vistazo a Stratego Octave Compiler .
(No lo he probado todavía, pero planeo hacerlo en los próximos días).
Ejecute mkoctfile --link-stand-alone embedded.cc -o embedded
De la solución de octava y no de un archivo por lotes.
Sólo te salvé medio día (-;
En la solución anterior en el punto 4 B:
B Busca algo obvio como "min" y no obtiene resultados. Esto se debe a que la función cargable "min" se encuentra en el archivo .oct "max.oct". Haga una copia de max.oct y cámbiele el nombre a min.oct. Funcionará ahora.
Es posible que esto no funcione si se llama a alguna función desde @folder function.m y también para evitar archivos duplicados innecesarios, simplemente agregue el siguiente código en algún lugar de su archivo m fuera de @folder
autoload ("min", "max.oct");
Asimismo, se puede eliminar mediante
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 + /
Solo para agregar que si desea ejecutar un script en lugar de una función m, entonces la línea de embedded.cc:
octave_value_list out = feval ("your_custom_m_file", in);
debiera ser:
octave_value_list out = feval ("your_custom_m_script");
También use ''cuales'' para encontrar dónde se empaquetan 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 / octave / 3.6.2 / oct / i686-pc-mingw32 / max.oct
Solución: cree un archivo ejecutable utilizando mkoctfile y empaquételo con los archivos centrales de Octave y otros archivos .oct y .m según sea necesario.
Paso 1: Crea un ejecutable independiente.
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;
}
Construye este archivo con el comando
mkoctfile --link-stand-alone embedded.cc -o embedded
Puede lanzar advertencias, pero mientras no arroje errores, debería estar bien. El archivo embedded.exe se compilará y se puede ejecutar. El único problema es que carecerá de todas las golosinas que hacen que la octava sea increíble. Tendrás que proporcionarlos.
Paso 2: Crear una carpeta de distribución
Deberá crear una copia de muchos de los archivos de Octave. 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 whack-a-mole
Ahora deberá averiguar qué otros archivos serán necesarios para ejecutar su script .m. Puede simplificar este paso copiando / oct / i686-pc-mingw32 * .oct y / share / octave / 3.2.4 / m / * / *. M al directorio de distribución, aunque esto será excesivo y en realidad no lo hará. Prevenir el paso whack-a-mole.
Ahora, debes jugar whack-a-mole o la tradición consagrada por el tiempo "¿Dónde está mi inclusión, yo?"
- Abra un indicador de cmd y navegue a su carpeta de distribución.
- Deshazte de cualquier cadena PATH útil. Tus clientes no los tendrán.
Intente ejecutar el programa embedded.exe. Recibirá un error como el siguiente:
embedded.exe
error: `max ''no definido cerca de la línea 83 columna 22
error: evaluando el número de elemento de la lista de argumentos 1
error: evaluando el número de elemento de la lista de argumentos 1
error: llamado desde:
error: T: / sms / Development / research / c2 / disttest / strcat.m en la línea 83, columna 3
error: T: / sms / Development / research / c2 / disttest / file_in_path.m en la línea 5, columna 10
error: T: / sms / Development / research / c2 / disttest / imread.m en la línea 50, columna 6Una búsqueda en su instalación de Octave para "max". Será un archivo .oct o .m. En este caso, es un archivo .oct, max.oct. Cópialo a tu directorio de distribución.
B Busca algo obvio como "min" y no obtiene resultados. Esto se debe a que la función cargable "min" se encuentra en el archivo .oct "max.oct". Haga una copia de max.oct y cámbiele el nombre a min.oct. Funcionará ahora. ¿Cómo sabes dónde están las funciones? No estoy seguro. La mayoría de ellos están en lugares obvios como "max.oct" para min, y "fft2.oct" para "ifft2.oct". Buena suerte con todo eso.
Repita hasta que se ejecute su ejecutable.
Tenía el mismo requisito (un clic, cerebro-simple), así que hice una configuración que solo contenía 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 archivo-m.
Esto descargará Octave 4.2.1 como un programa portátil (32 bits, de lo contrario tendríamos que descargarlo nuevamente si el sistema resulta ser de 32 bits), descomprima usando el script vbs, mueva el contenido a la misma carpeta que el lote Archivo y ejecutarlo en modo GUI. Cada vez que se llame al mismo script, solo se comprobará si octave.bat todavía está allí.
Por supuesto, esto se traduce en una gran pérdida de espacio en el disco, descargando el zip de 280MB, que se desempaqueta a más de 1GB (que empeoraré al no eliminar el zip más adelante), y te quedas con una ventana de cmd que no es fácil 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). En 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 induce el dolor de cabeza que pude 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." )