Reputation: 915
Im am using octave under windows (native) and try to compile a c++ program into a mex file and link some libraries to it:
% 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);
When run, the output of the command is:
>> 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
I also tried to run the string directly from the command line:
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
with the same result. While the -I command appears to work well, why does the -L argument causes problems? What would be the right way to escape the path names with spaces? Double quotes also won't work.
EDIT Based on the answers, I am using mex() in its functional form, but the result is still the same:
vxipath = getenv('VXIPNPPATH');
params={};
params{1} = sprintf('-I%s', fullfile(vxipath, 'Winnt', 'Include'));
params{2} = sprintf('-L%s', fullfile(vxipath, 'Winnt', 'lib_x64', 'msc'));
params{3} = sprintf('-lvisa64.lib');
% replace \ with /
for i1=1:length(params)
s = params{i1};
s(s=='\') = '/';
params{i1} = s;
end
params
mex("main.cpp", params{:});
Gives the output:
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
Which is the same result as before. Additional observations are:
I also tried it directly from the bash shell with the corresponding command with the same result.
Upvotes: 1
Views: 646
Reputation: 915
mkoctfile
does not escape the arguments properly if they contain spaces and it does not like backslashes in Octave's own paths.
It creates the following two commands:
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
When I change it to the following:
\
with /
-LC:\Program Files...
to "-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
It will compile without error.
Upvotes: 1
Reputation: 60514
This doesn't answer the how to fix it, as rahnema1 already did that. But I'll show you how to simplify your code.
Do not use eval
. eval
is evil.
Instead of evaluating a string function paramA paramB
, call function
directly with string input arguments. function paramA paramB
is translated by the interpreter to a call function('paramA','paramB')
. But it is a lot easier to generate the latter form, and you get to avoid eval
to boot:
params = {};
params{1} = '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include';
params{2} = '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc';
params{2} = '-lvisa64.lib';
mex('main.cpp', params{:});
Properly generate paths using fullfile
. It adds /
or \
depending on which platform you're on, plus I find it easier to read:
include_path = fullfile(getenv('VXIPNPPATH'), 'Winnt', 'Include');
params{1} = ['-I', include_path];
Upvotes: 1
Reputation: 15837
Replace backslashes with slashes and place each argument inside single quotes.
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'
or
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')
Upvotes: 1