2016-07-20 15 views
1

Wir verwenden eine Scripting-Umgebung, um eine eigenständige ausführbare Datei automatisch zu erstellen, auszuführen und zu verifizieren. Wir arbeiten mit Matlab R2010a x64. Der Matlab-Compiler mcc wird von der Windows-Befehlszeile den Aufbau einer eigenständigen Anwendung aufgerufen:Wie kann ich sicherstellen, dass Matlab mcc nicht unvollständige eigenständige ausführbare Dateien erstellt?

mcc -m -v -w ermöglichen -I source_folder -I common_folder -a specific_files_we_need our_program

Das Programm von etwa 25 besteht Module (.m-Dateien) und verwendet etwa 5 Toolboxen. Dies funktioniert solange die korrekte Lizenz verfügbar ist. mcc prüft, ob eine Compiler-Lizenz verfügbar ist, löst Abhängigkeiten auf und packt alles in die ausführbare Datei.

Wenn die Lizenz jedoch nicht die erforderlichen Toolboxen enthält, gibt mcc keine Warnung oder Fehler aus. Es erstellt die ausführbare Datei ohne die Toolboxes. Die ausführbare Datei startet also, scheint auf den ersten Blick zu laufen, stürzt aber ab, wenn eine Codezeile erreicht wird, die eine Toolbox benötigt.

Ich erwarte von einem Compiler, dass es mich über fehlende Komponenten informiert. Was kann ich tun, um mich über fehlende Komponenten zu informieren? Wie kann ich sicherstellen, dass mcc unvollständige ausführbare Dateien nicht zusammenstellt? Fehle ich etwas im Anruf zum MC?

Am liebsten würde ich das Kompilieren so einrichten, dass es aufhört, wenn Dinge fehlen.

\ Zweikeks

Antwort

1

Der einfachste Weg ist in Ihrer Zusammenstellung Skript können Sie die erforderlichen Lizenzen Kasse, dh

license('checkout','Compiler') 
license('checkout','control_toolbox') 

Sie nur die 5 Werkzeugkästen hinzufügen, die ausgecheckt werden müssen -> wenn die Lizenz Die Funktion kann die Lizenz nicht auschecken, sie gibt false zurück, mit der Sie dann die Kompilierung abbrechen können.

+0

Dies hilft dank schon matlabgui. Ich muss jedoch eine feste Reihe von Toolboxen angeben. Wenn ein Entwickler die Quellen so ändert, dass eine andere Toolbox benötigt wird, kann die Kompilierung ohne vorherige Benachrichtigung erneut fehlschlagen. – Zweikeks

+0

Das stimmt. Sie könnten möglicherweise alle abhängigen Quelldateien durchlaufen und sehen, aus welcher Toolbox sie stammen. – matlabgui

0

Das ist, was ich kam schließlich mit:

ich vor der Kompilierung überprüfen, die Werkzeugkästen benötigt werden und rufen Lizenz (entsprechend). Oder ich kann einen eingebauten Check in die ausführbare Datei selbst implementieren. (Wird nach dem Kompilieren mit einem speziellen Parameter aufgerufen, löst eine Selbstprüfung auf verfügbare Toolboxen aus.) In beiden Fällen benötige ich die Namen der benötigten Toolboxen.

Ich habe verschiedene Möglichkeiten ausprobiert, um eine Liste von Toolboxen zu erstellen. Kurz gesagt: Das Ausführen des Programms in Matlab und das Eingeben der Lizenz ('inuse') ist nicht sehr zuverlässig. depfun() steigt zu viel ab. mydepfun() und fdep() steigen nicht genug ab.

Ich denke, das Problem mit mydepfun() und fdep() ist, dass sie nicht in den \ toolbox \ shared-Ordner abstammen. Also nahm ich mydepfun() von Tobias Kienzler (link to the original sources) und es geändert:

function [list,callers,tboxes_found] = i_scan(f) 

func = i_function_name(f); 

[list,~,~,~,~,~,callers,~] = depfun(func,'-toponly','-quiet'); 

toolboxroot = fullfile(matlabroot,'toolbox'); 
sharedroot = strcat(toolboxroot, filesep, 'shared'); 

intoolbox = strncmpi(list,toolboxroot,numel(toolboxroot)); 
inshared = strncmpi(list,sharedroot, numel(sharedroot)); 

tboxes_found = list(intoolbox & ~inshared); 
tboxes_found = regexpi(tboxes_found, '[\\/]toolbox[\\/](.+?)[\\/]', 'tokens'); 
tboxes_found = cellfun(@(cfun) cfun{1}, tboxes_found); 

list = list(~intoolbox | inshared); 
callers = callers(~intoolbox | inshared); 
for jj = 1:numel(list) 
    c = callers{jj}; 
    cs = cell(numel(c),1); 
    for kk = 1:numel(c) 
     cs{kk} = list{c(kk)}; 
    end; 
    callers{jj} = cs; 
end; 

Auf diese Weise i_scan (f) die Werkzeugkästen Rückkehr und senkt sich auch in \ Toolbox \ geteilt. Die Hauptfunktion von mydepfun() sammelt nur die Werkzeugkästen:

function [filelist,callers,toolboxes] = mydepfun(fn,recursive) 
. 
. 
toolboxes = {}; 
[filelist,callers,tboxes_found] = i_scan(foundfile); 
toolboxes = [toolboxes; tboxes_found]; 
. 
. 
[newlist,newcallers,tboxes_found] = i_scan(toscan{1}); 
toolboxes = [toolboxes; tboxes_found]; 
. 
. 
toolboxes = unique(toolboxes); 

Die aufgeführten Werkzeugkästen sind die, die unseren Quellcode verwendet. Die modifizierte mydepfun() scheint gut zu funktionieren. (Abgesehen von den typischen Problemen, die durch Elemente verursacht werden, die nur während der Laufzeit aufgelöst werden, wie eval(), Funktionsgriffe, Callbacks etc.)

Und: Die Abhängigen, die ich gesehen habe - wie mydepfun() - benutzen depunf() drin .depfun() ist nicht zuverlässig, da es den gesamten Quellcode ignoriert, der sich nicht auf dem Pfad befindet (auch die Rückgabe prob_files ist in diesem Fall leer). Es ist also darauf zu achten, dass der Matlab-Pfad korrekt eingestellt ist. (Auch zusätzliche Pfade sind problematisch, da Matlab unerwartet Funktionen mit dem gleichen Namen von anderen Orten übernehmen kann.)

Schließlich denke ich, dies ist ein guter Weg, um meinen Build-Prozess zuverlässiger zu machen.

/Zweikeks

0

Ich habe gerade einen weiteren Hinweis aus dem Mathworks Forum. Der Compiler schreibt mccExludedFiles.log aus. Dies führt fehlende Toolboxes auf. Zum Beispiel

mccExludedFiles.log: 
C:\Program Files\MATLAB\R2010a\toolbox\shared\optimlib\fmincon.m 
called by ...c:\temp\whatever\source\code.m 
(because the required licenses are not available.) 

(Andere fehlende Dateien im Quellcode nicht aufgelistet bekommen, though.)

/Zweikeks