Octave: how to specify arguments for mkoctfile - octave

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:
'/' or '\' does not make a difference
if I omit all parameters, I get a missing-include-file-error: OK
if I omit the '-L' argument, I get a missing-lib-file-error: OK
if I add the '-L' argument, I get the error shown above: It appears that the -L argument behaves differently than the -I argument.
I also tried it directly from the bash shell with the corresponding command with the same result.

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')

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];

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:
replace \ with /
specify the library name without .lib extension
escape -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.

Related

Static linking with cublas

I want to link my program with the static version of cublas, but I get some undefined references. The command and error are
$ nvcc test.cu -o test --cudart=static -ldl -lpthread -lcurand_static -lcublas_static -lculibos
/home/mahmood/cuda_10.1.168/bin/../targets/x86_64-linux/lib/libcublas_static.a(cublas.o): In function `cublasCtxInit(cublasContext**)':
cublas.compute_75.cudafe1.cpp:(.text+0x34b): undefined reference to `cublasLtCtxInit'
cublas.compute_75.cudafe1.cpp:(.text+0x417): undefined reference to `init_gemm_select'
...
...
In fact, the library path is fine and the cublasLtCtxInit exists in the static library file.
$ ls -l /home/mahmood/cuda_10.1.168/lib64/libcublas_static.a
-rw-rw-r-- 1 mahmood mahmood 75127082 Jun 27 16:06 /home/mahmood/cuda_10.1.168/lib64/libcublas_static.a
$ grep cublasLtCtxInit ~/cuda_10.1.168/lib64/libcublas_static.a
Binary file /home/mahmood/cuda_10.1.168/lib64/libcublas_static.a matches
$ echo $LD_LIBRARY_PATH
/home/mahmood/cuda_10.1.168/lib64:
So, how can I fix that?
The correct static linking sequence with cublas can be found in the Makefile for the conjugateGradient CUDA sample code.
The needed switches for nvcc are:
-lcublas_static -lcublasLt_static -lculibos
example:
$ cat t1752.cu
#include <cublas_v2.h>
int main(){
cublasHandle_t h;
cublasCreate(&h);
}
$ nvcc t1752.cu -o t1752 -lcublas_static -lcublasLt_static -lculibos
$

Add MySQL to my Makefile gives problems

I have a problem with my C project built under Debian Jessie. After doing some stuffs now I need to work with MySQL so i download the library and try to update my Makefile.
This is my Makefile right now
CC = gcc
CFLAGS = -Wall -Wextra
LDFLAGS = -lbluetooth -lpthread -lmysqlclient
LFLAGS = -lm
INC = -I/usr/include/mysql
SOURCES = stb.c btscan.c and.c gima.c database.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = stb
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $# $(LFLAGS) $(LDFLAGS)
stb.o: btscan.h and.h gima.h database.h
btscan.o: btscan.h
and.o: and.h
gima.o: gima.h
database.o: database.h
clean:
#rm -f *.o *.out stb
and this is the files where I want to use the library
stb.c
#include "btscan.h"
#include "and.h"
#include "gima.h"
#include "database.h"
struct device* bt_devices;
struct device* ble_devices;
int main(void) {
//-------------------------------- DATABASE CONNECTION ----------------
//MYSQL *con = mysql_init(NULL);
....... }
and finally database.h
#ifndef _DATABASE_H
#define _DATABASE_H
#include <my_global.h>
#include <mysql.h>
#endif
When I try to make i receive "Fatal error : my_global.h No such file or directory". However if i try MySQL on a single test file and compiling it with
gcc -o test test.c -I/usr/include/mysql -lmysqlclient
it works. Where I made a mistake?
Thanks in advance
If you'd shown us the output of the compiler, or examine it yourself, you'll immediately see that what you're running on the command line is not the same at all as what make is running: in particular make is not adding the -I/usr/include/mysql flag to the command line.
That's because in your makefile you set:
INC = -I/usr/include/mysql
but nowhere in your makefile (as you've shown it) is the variable INC actually used, so this is essentially a no-op.
Since you're using the standard GNU make compilation rules, you should be setting standard GNU make variables:
CPPFLAGS = -I/usr/include/mysql

BitBake: How to use shell script content as body of pkg_postinst or pkg_preinst functions?

I want to add the contents of a shell script into the body of pkg_preinst_${PN} or pkg_postinst_${PN} function (BitBake recipe of a software package).
For example, let's consider this "PREINST" shell script:
$ cat PREINST
#! /bin/sh
chmod +x /usr/bin/mybin
Executing a simple 'cat' command inside pkg_preinst function doesn't work:
pkg_preinst_${PN}() {
cat ${S}/path/to/PREINST
}
In this way, the contents for the .spec file for the generated rpm package are not the expected:
%pre
cat /Full/Path/To/Variable/S/path/to/PREINST
As you can see, %pre section doesn't include real contents of PREINST file, just includes the 'cat' command.
Is it possible to include the contents of PREINST file into the generated .spec file in some way?
Thank you in advance!
Finally I solved this issue by prepending this code to the do_package task:
do_package_prepend() {
PREINST_path = "${S}/${MYMODULE}/PREINST"
POSTINST_path = "${S}/${MYMODULE}/POSTINST"
PREINST = open(PREINST_path, "r")
POSTINST = open(POSTINST_path, "r")
d.setVar("pkg_preinst", PREINST.read())
d.setVar("pkg_postinst", POSTINST.read())
}
It modifies "pkg_preinst" and "pkg_postinst" keys in 'd' global dictionary with the content of each PREINST and POSTINST file as value. Now it works! :)

CUDA separable compilation and CMake

I have a large library project that contains both cpp and cu source files. I'd like to compile it in a standalone shared object, but since I have some device functions I decided to split it in a shared object containing the majority of the functions and an archive file containing the device functions only. Here's part of the Makefile I wrote for it - all the (non-template) device functions have been put in the file device.cu:
Makefile
LIB_NAME = libexample.so
CUDA = /usr/local/cuda/include
CXX = g++
CXXFLAGS = -c -O2 -fPIC -Wall -I. -I./code -I./code/header -I$(CUDA)
SOURCES = src1.cpp src2.cpp src3.cpp
OBJECTS = $(SOURCES:.cpp=.o)
NVCC = nvcc
CU_SOURCES = src1_cu.cu src2_cu.cu src3_cu.cu device.cu
CU_OBJECTS = $(CU_SOURCES:.cu=.o)
BUILDDIR = .
VPATH = code/src/common_src code/src/src_CUDA
DEVICE_LINK = dev_link.o
GENCODE_FLAGS := -gencode arch=compute_20,code=sm_20
NVCCFLAGS = -x cu -O2 --compiler-options '-fPIC' $(GENCODE_FLAGS) -I. -I./code -I./code/header -I$(CUDA) -dc
NVCCLINK = --compiler-options '-fPIC' $(GENCODE_FLAGS) -dlink
all: lib/$(LIB_NAME)
lib/$(LIB_NAME): $(OBJECTS) $(CU_OBJECTS) $(DEVICE_LINK)
$(CXX) -shared -Wl,-soname,libexample.so $^ -o $#
ar rcs lib/device.a device.o
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
%.o: %.cu
$(NVCC) $(NVCCFLAGS) $< -o $#
$(DEVICE_LINK): $(CU_OBJECTS)
$(NVCC) $(NVCCLINK) $^ -o $#
I decided to change my build system and I switched to CMake to produce both Makefiles and Visual Studio projects. It's obvious how to write a working CMakeLists.txt file without separable compilation, but I couldn't find a solution that works in my case (I read some proposed solutions here on S.O. but they don't seem to work for me!). Can you help me to write said CMakeLists.txt file? Here's what I did so far:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.10)
# Set Library & project name
set(LIB_NAME example)
project(${LIB_NAME})
message("LIBRARY ${LIB_NAME}")
enable_language(CXX)
# Check if CUDA is installed on this system
find_package(CUDA REQUIRED)
# Set source directories
set(COMMON_SRCS_DIR ${CMAKE_SOURCE_DIR}/code/src/common_src)
set(CUDA_SRCS_DIR ${CMAKE_SOURCE_DIR}/code/src/src_CUDA)
# Set source files
set(COMMON_SRCS ${COMMON_SRCS_DIR}/src1.cpp
${COMMON_SRCS_DIR}/src2.cpp
${COMMON_SRCS_DIR}/src3.cpp
)
# Set CUDA device library name
set(DEVICE_LIB "device")
# Set CUDA objects
cuda_compile(SRC1_CU_O ${CUDA_SRCS_DIR}/src1_cu.cu)
cuda_compile(SRC2_CU_O ${CUDA_SRCS_DIR}/src2_cu.cu)
cuda_compile(SRC3_CU_O ${CUDA_SRCS_DIR}/src3_cu.cu)
cuda_compile(DEVICE_CU_O ${CUDA_SRCS_DIR}/device.cu)
# Set header file directories
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/code)
include_directories(${CMAKE_SOURCE_DIR}/code/header)
include_directories(${CUDA_INCLUDE_DIRS})
# Get CUDA compute capability - contains CUDA_GENCODE define
include(CudaParams.cmake)
# Set include stuff
cuda_include_directories(${CMAKE_SOURCE_DIR})
cuda_include_directories(${CMAKE_SOURCE_DIR}/code)
cuda_include_directories(${CMAKE_SOURCE_DIR}/code/header)
cuda_include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_SEPARABLE_COMPILATION ON)
# Set compiler flags
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${CUDA_GENCODE} --compiler-options '-fPIC' -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -march=native -O2")
# Generate main target
cuda_add_library(${LIB_NAME} SHARED ${COMMON_SRCS}
${SRC1_CU_O} ${SRC2_CU_O} ${SRC3_CU_O} ${DEVICE_CU_O})
cuda_add_library(${DEVICE_LIB} STATIC ${DEVICE_CU_O})
# Install instructions
INSTALL(TARGETS ${LIB_NAME}
LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/lib
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/lib
)
As you can see, there's no dev_link.o mention in the CMakeLists.txt file because I simply don't know where I could put it!

Capture command output inside zsh function

I'm trying to write a zsh function to get the path to a python module.
This works:
pywhere() {
python -c "import $1; print $1.__file__"
}
However, what I'd really like is the dir path without the filename. This doesn't work:
pywhere() {
dirname $(python -c "import $1; print $1.__file__")
}
Note: it works in bash, but not in zsh!
EDIT this is the error:
~ % pywhere() {
function → dirname $(python -c "import $1; print $1.__file__")
function → }
File "<string>", line 1
import pywhere() {
^
SyntaxError: invalid syntax
Your problem is due to a broken preexec: you aren't quoting the command line properly when you print it for inclusion in the window title.
In the .zshrc you posted, which is not the one you used (don't do that! Always copy-paste the exact file contents and commands that you used), I see:
a=${(V)1//\%/\%\%}
a=$(print -Pn "%40>...>$a" | tr -d "\n")
print -Pn "\ek$a:$3\e\\"
print -P causes prompt expansion. You include the command in the argument. You protect the % characters in the command by doubling them, but that's not enough. You evidently have the prompt_subst option turned on, so print -P causes the $(…) construct in the command line that defines the function to be executed:
python -c "import $1; print $1.__file__"
where $1 is the command line (the function definition: pywhere { … }).
Rather than attempt to parse the command line, print it out literally. This'll also correct other mistakes: beyond not taking prompt_subst into account, you doubled % signs but should have quadrupled them since you perform prompt expansion twice, and you expand \ sequences twice as well.
function title() {
a=${(q)1} # show control characters as escape sequences
if [[ $#a -gt 40 ]]; then a=$a[1,37]...; fi
case $TERM in
screen)
print -Pn "\ek"; print -r -- $a; print -Pn ":$3\e\\";;
xterm*|rxvt)
print -Pn "\e]2;$2 | "; print -r -- $a; print -Pn ":$3\a";;
esac
}
Why not just use this:
python -c "import os, $1; print os.path.dirname($1.__file__)"