Octave:如何为 mkoctfile 指定参数

Posted

技术标签:

【中文标题】Octave:如何为 mkoctfile 指定参数【英文标题】:Octave: how to specify arguments for mkoctfile 【发布时间】:2019-09-13 13:17:46 【问题描述】:

我在 windows (native) 下使用 octave 并尝试将 c++ 程序编译成 mex 文件并将一些库链接到它:

% compile for octave
cmd = sprintf("mex main.cpp -I\"%s\\Winnt\\Include\" -L\"%s\\Winnt\\lib_x64\\msc\" -lvisa64.lib", ...
getenv('VXIPNPPATH'), getenv('VXIPNPPATH'))
eval(cmd);

运行时,命令的输出为:

>> mex main.cpp -I'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\Include' -L'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\lib_x64\msc' -lvisa64.lib
g++: error: Files: No such file or directory
g++: error: (x86)\IVI: No such file or directory
g++: error: Foundation\VISA\\Winnt\lib_x64\msc: No such file or directory
warning: mkoctfile: building exited with failure status

我也试过直接从命令行运行字符串:

mex main.cpp -I'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\Include' -L'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\lib_x64\msc' -lvisa64.lib

结果相同。 虽然 -I 命令似乎运行良好,但为什么 -L 参数会导致问题?用空格转义路径名的正确方法是什么? 双引号也不起作用。

编辑 根据答案,我以函数形式使用 mex(),但结果仍然相同:

vxipath = getenv('VXIPNPPATH');
params=;
params1 = sprintf('-I%s', fullfile(vxipath, 'Winnt', 'Include'));
params2 = sprintf('-L%s', fullfile(vxipath, 'Winnt', 'lib_x64', 'msc'));
params3 = sprintf('-lvisa64.lib');

% replace \ with /
for i1=1:length(params)
  s = paramsi1;
  s(s=='\') = '/';
  paramsi1 = s;
end

params
mex("main.cpp", params:);

给出输出:

params =

  [1,1] = -IC:/Program Files (x86)/IVI Foundation/VISA/Winnt/Include
  [1,2] = -LC:/Program Files (x86)/IVI Foundation/VISA/Winnt/lib_x64/msc
  [1,3] = -lvisa64.lib


g++: error: Files: No such file or directory
g++: error: (x86)/IVI: No such file or directory
g++: error: Foundation/VISA/Winnt/lib_x64/msc: No such file or directory
warning: mkoctfile: building exited with failure status

这与之前的结果相同。其他观察结果是:

'/' 或 '\' 没有区别 如果我省略所有参数,我会收到缺少包含文件的错误:OK 如果我省略 '-L' 参数,我会收到 missing-lib-file-error: OK 如果我添加“-L”参数,我会收到上面显示的错误:-L 参数的行为似乎与 -I 参数不同。

我也直接从 bash shell 中用相应的命令进行了尝试,结果相同。

【问题讨论】:

mex("main.cpp", params:) 请将-v(详细)标志添加到您的mex 命令中,以便我们查看正在执行的链接器命令。我认为 Octave 可能没有正确转义 shell 命令。 @CrisLuengo:感谢 -v。这正是问题所在。显然 mkoctfile 在 windows 下被破坏了。在单独的答案中查看结果。 【参考方案1】:

用斜杠替换反斜杠并将每个参数放在单引号内。

mex 'main.cpp' '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include' '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc' '-lvisa64.lib'

mex ('main.cpp', '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include', '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc', '-lvisa64.lib')

【讨论】:

好像没什么区别。请看我上面的编辑。【参考方案2】:

这并没有回答如何解决它,如rahnema1 already did that。但我会告诉你如何简化你的代码。

    不要使用evaleval is evil.

    不计算字符串function paramA paramB,而是直接使用字符串输入参数调用functionfunction paramA paramB 被解释器翻译成调用function('paramA','paramB')。但是生成后一种形式要容易得多,而且你可以避免eval 启动:

    params = ;
    params1 = '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include';
    params2 = '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc';
    params2 = '-lvisa64.lib';
    mex('main.cpp', params:);
    

    使用fullfile 正确生成路径。它会根据您使用的平台添加/\,而且我发现它更易于阅读:

    include_path = fullfile(getenv('VXIPNPPATH'), 'Winnt', 'Include');
    params1 = ['-I', include_path];
    

【讨论】:

fullfile 不会将 \ 替换为 /。再次需要额外的工作include_path(include_path=='\')='/'; @rahnema1:我没有意识到这一点。 Octave 对分隔符很挑剔吗?我认为 MATLAB 会在 Windows 上自动将正斜杠转换为反斜杠,但通常在调用 mex 时您会在 Windows 上使用反斜杠。 Octave 最初是为非 Windows 系统开发的,并且移植到 Windows 是通过交叉编译完成的,因此最终我们可以看到这种不兼容性。 好像没什么区别。请看我上面的编辑。【参考方案3】:

mkoctfile 如果参数包含空格并且不喜欢 Octave 自身路径中的反斜杠,则不会正确转义参数。 它创建以下两个命令:

g++ -c -I/release/mxe-octave-w64/usr/x86_64-w64-mingw32/include  -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave\.. -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave -IC:\Octave\OCTAVE~1.0\\mingw64\include   -fopenmp -g -O2   -I. "-IC:\Program Files (x86)\IVI Foundation\VISA\Winnt\Include"  -DMEX_DEBUG main.cpp -o C:\Octave\OCTAVE~1.0\tmp/oct-u4r15I.o
g++ -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave\.. -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave -IC:\Octave\OCTAVE~1.0\\mingw64\include   -fopenmp -g -O2 -shared -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols  -o main.mex  C:\Octave\OCTAVE~1.0\tmp/oct-u4r15I.o  -lvisa64.lib  -LC:\Program Files (x86)\IVI Foundation\VISA\Winnt\lib_x64\msc -LC:\Octave\OCTAVE~1.0\\mingw64\lib\octave\5.1.0 -LC:\Octave\OCTAVE~1.0\\mingw64\lib -LC:\Octave\OCTAVE~1.0\\mingw64\lib\octave\5.1.0 -loctinterp -loctave  -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols 

当我将其更改为以下内容时:

\ 替换为/ 指定不带 .lib 扩展名的库名称 转义-LC:\Program Files..."-LC:\Program Files..."
g++ -c -I/release/mxe-octave-w64/usr/x86_64-w64-mingw32/include  -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave/.. -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave -IC:/Octave/OCTAVE~1.0//mingw64/include   -fopenmp -g -O2   -I. "-IC:/Program Files (x86)/IVI Foundation/VISA/Winnt/Include"  -DMEX_DEBUG main.cpp -o C:/Octave/OCTAVE~1.0/tmp/oct-u4r15I.o  
g++ -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave/.. -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave -IC:/Octave/OCTAVE~1.0//mingw64/include   -fopenmp -g -O2 -shared -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols  -o main.mex  C:/Octave/OCTAVE~1.0/tmp/oct-u4r15I.o "-LC:/Program Files (x86)/IVI Foundation/VISA/Winnt/lib_x64/msc" -lvisa64 -LC:/Octave/OCTAVE~1.0//mingw64/lib/octave/5.1.0 -LC:/Octave/OCTAVE~1.0//mingw64/lib -LC:/Octave/OCTAVE~1.0//mingw64/lib/octave/5.1.0 -loctinterp -loctave  -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols 

它将无错误地编译。

【讨论】:

可能显示实际的mex 调用,我假设您的意思是在字符串中包含" 引号,如下所示:'"-L..."'? 第一个框中的两个 g++ 调用是 mex() 生成的。我需要进行这两项更改才能使其正常工作。 哦,所以你是直接在shell中执行那些g++调用? 是的,在与octave一起安装的bash shell中。

以上是关于Octave:如何为 mkoctfile 指定参数的主要内容,如果未能解决你的问题,请参考以下文章

包含多个 C 和 C++ 源文件的 mkoctfile

在Ubuntu14.04中安装Octave的Vlfeat

使用 seaborn 绘图时,如何为色调参数指定多个变量?

如何为 google chrome adobe pdf 查看器指定参数?

如何为自定义类的参数指定类型提示? [复制]

对于将 HTTP/JSON 转码为 gRPC,如何为枚举指定查询参数