utility for shared library management
ilib_build(lib_name,table,files,libs [,makename,ldflags,cflags,fflags,ismex, cc])
: :cc Provide the name of the C compiler. :
This tool is used to create shared libraries and to generate a loader file which can be used to dynamically load the shared library into Scilab with addinter
Many examples are provided in SCI/modules/dynamic_link/examples directory. They are all released into the public domain.
Note that a compiler must be available on the system to use this function.
Languages handle by this function are: C, C++, Fortran and Fortran 90.
On the internal technical level, under GNU/Linux and Mac OS X, the ilib_* function are based on the autotools. First, a configure is executed to detect compilers available. Then, a make is launched with the provided arguments. For more information: `Full technical description of the incremental link / dynamic link`_
Since version 5.3.2, under GNU/Linux, Scilab detects where the libstdc++ is located (thanks to the command gcc -print-search- dirs|grep ^install:|awk ‘{print $2}’ ). Previously, the dynamic link was using the libstdc++ embedded in Scilab.
//Here with give a complete example on adding new primitive to Scilab
//create the procedure files
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_c');
`cd`_('example_ilib_build_c');
f1=['extern double fun2();'
'void fun1(double *x, double *y)'
'{*y=fun2(*x)/(*x);}'];
`mputl`_(f1,TMPDIR + '/example_ilib_build_c/fun1.c');
f2=['#include <math.h>'
'double fun2(double x)'
'{ return( sin(x+1.));}'];
`mputl`_(f2,TMPDIR + '/example_ilib_build_c/fun2.c');
//creating the interface file
i=['#include <stdlib.h>'
'#include <api_scilab.h>'
'#include <Scierror.h>'
'#include <localization.h>'
''
'extern int fun1 ( double *x, double *y);'
''
'int sci_fun1(char *fname)'
'{'
' int iType1 = 0;'
' SciErr sciErr;'
' int m1 = 0, n1 = 0;'
' double *pdVarOne = NULL;'
' int *piAddressVarOne = NULL;'
''
' CheckRhs(1,1);'
' CheckLhs(1,1);'
''
' sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType1);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' if (iType1 != sci_matrix)'
' {'
' Scierror(999,_(""%s: Wrong type for input argument #%d: A string expected.\n""), fname, 1);'
' return 0;'
' }'
''
' sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarOne, &m1, &n1, &pdVarOne);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' fun1(pdVarOne, pdVarOne);'
' LhsVar(1) = 1;'
' return 0;'
'}'];
`mputl`_(i,TMPDIR + '/example_ilib_build_c/sci_fun1.c');
//creating the shared library (a gateway, a Makefile and a loader are
//generated.
files=['fun1.c','fun2.c','sci_fun1.c'];
ilib_build('build_c',['fun1','sci_fun1'],files,[]);
// load the shared library
`exec`_ loader.sce;
//using the new primitive
fun1(33)
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_c_old');
`cd`_('example_ilib_build_c_old');
//Here with give a complete example on adding new primitive to Scilab
//create the procedure files
f1=['extern double fun2();'
'void fun1(double *x, double *y)'
'{*y=fun2(*x)/(*x);}'];
`mputl`_(f1,'fun1.c')
f2=['#include <math.h>'
'double fun2(double x)'
'{ return( sin(x+1.));}'];
`mputl`_(f2,'fun2.c');
//creating the interface file
i=['#include ""stack-c.h""'
'#include ""stackTypeVariable.h""'
'#include ""version.h""'
'#if SCI_VERSION_MAJOR <= 5'
'#if SCI_VERSION_MINOR < 2'
' #error ""This example is obsolete see help ilib_buid""'
'#endif'
'#endif'
''
'extern int fun1 ( double *x, double *y);'
'int intfun1(char *fname)'
'{'
' int m1,n1,l1;'
' CheckRhs(1,1);'
' CheckLhs(1,1);'
' GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);'
' fun1(stk(l1),stk(l1));'
' LhsVar(1) = 1;'
' return 0;'
'}'];
`mputl`_(i,'intfun1.c')
//creating the shared library (a gateway, a Makefile and a loader are
//generated.
files=['fun1.c','fun2.c','intfun1.c'];
ilib_build('ilib_c_old',['scifun1','intfun1'],files,[]);
// load the shared library
`exec`_ loader.sce
//using the new primitive
scifun1(33)
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_cpp');
`cd`_('example_ilib_build_cpp');
i=['#include <string>'
'extern ""C"" {'
'#include <stdlib.h>'
'#include <api_scilab.h>'
'#include <localization.h>'
'#include <Scierror.h>'
''
'int sci_cppfind(char *fname)'
'{'
''
' SciErr sciErr;'
' int *piAddressVarOne = NULL;'
' char *pStVarOne = NULL;'
' int iType1 = 0;'
' int lenStVarOne = 0;'
' int m1 = 0, n1 = 0;'
''
' int *piAddressVarTwo = NULL;'
' char *pStVarTwo = NULL;'
' int iType2 = 0;'
' int lenStVarTwo = 0;'
' int m2 = 0, n2 = 0;'
''
' int m_out = 0;'
' int n_out = 0;'
''
' sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType1);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' if (iType1 != sci_strings)'
' {'
' Scierror(999,_(""%s: Wrong type for input argument #%d: A string expected.\n""), fname, 1);'
' return 0;'
' }'
''
' sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iType2);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' if (iType2 != sci_strings)'
' {'
' Scierror(999,_(""%s: Wrong type for input argument #%d: A string expected.\n""), fname, 2);'
' return 0;'
' }'
''
' sciErr = getMatrixOfString(pvApiCtx, piAddressVarOne, &m1, &n1, &lenStVarOne, &pStVarOne);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' pStVarOne = new char[lenStVarOne + 1];'
' if (pStVarOne == NULL)'
' {'
' Scierror(999,_(""%s: Memory allocation error.\n""),fname);'
' return 0;'
' }'
''
' sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &m2, &n2, &lenStVarTwo, &pStVarTwo);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' pStVarTwo = new char[lenStVarTwo + 1];'
' if (pStVarTwo == NULL)'
' {'
' Scierror(999,_(""%s: Memory allocation error.\n""),fname);'
' return 0;'
' }'
''
' sciErr = getMatrixOfString(pvApiCtx, piAddressVarOne, &m1, &n1, &lenStVarOne, &pStVarOne);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &m2, &n2, &lenStVarTwo, &pStVarTwo);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' std::string myMessage(pStVarOne);'
' std::string search(pStVarTwo);'
' delete pStVarTwo;'
' delete pStVarOne;'
' double dOut = 0.0;'
''
' if (myMessage.find(search) != std::string::npos) {'
' dOut = myMessage.find(search); /* The actual operation */'
' } else {'
' dOut = -1; /* Substring not found */'
' }'
' m_out = 1;'
' n_out = 1;'
' sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, m_out, n_out, &dOut);'
' if(sciErr.iErr)'
' {'
' printError(&sciErr, 0);'
' return 0;'
' }'
''
' LhsVar(1) = Rhs + 1;'
' return 0;'
'} /* extern ""C"" */'
'}'];
`mputl`_(i,TMPDIR + '/example_ilib_build_cpp/sci_cppfind.cxx');
//creating the shared library (a gateway, a Makefile and a loader are
//generated.
files = ['sci_cppfind.cxx'];
ilib_build('ilib_build_cpp',['cppfind','sci_cppfind'],files,[]);
// load the shared library
`exec`_ loader.sce;
// Small test to see if the function is actually working.
if cppfind("my very long string","long") <> 8 pause, end
if cppfind("my very long string","very") <> 3 pause, end
if cppfind("my very long string","short") <> -1 pause, end
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_cpp_old');
`cd`_('example_ilib_build_cpp_old');
i=['#include <string>'
'extern ""C"" {'
'#include ""stack-c.h""'
'#include ""version.h""'
'#if SCI_VERSION_MAJOR <= 5'
'#if SCI_VERSION_MINOR < 2'
' #error ""This example is obsolete see help ilib_buid""'
'#endif'
'#endif'
''
'int sci_cppfind(char *fname) {'
' int m1 = 0, n1 = 0, l1;'
' char *inputString1, *inputString2;'
' int m2 = 0, n2 = 0, l2;'
' int m3 = 0, n3 = 0;'
' double *position = NULL; /* Where we will store the position */'
' CheckRhs(2,2); /* Check the number of input argument */'
' CheckLhs(1,1); /* Check the number of output argument */'
' GetRhsVar(1, ""c"", &m1, &n1, &l1); /* Retrieve the first input argument */'
' inputString1=cstk(l1);'
' GetRhsVar(2, ""c"", &m2, &n2, &l2); /* Retrieve the second input argument */'
' inputString2=cstk(l2);'
' std::string myMessage (inputString1);'
' std::string search (inputString2);'
' m3=1;n3=1;'
' position = new double[1];'
' if (myMessage.find(search) != std::string::npos) {'
' position[0] = myMessage.find(search); /* The actual operation */'
' } else {'
' position[0] = -1; /* Substring not found */'
' }'
' CreateVarFromPtr(Rhs+1,""d"",&m3,&n3,&position); /* Create the output argument */'
' LhsVar(1) = Rhs+1;'
' delete[] position;'
' return 0;'
'}'
'}'];
`mputl`_(i,'sci_cppfind.cxx');
//creating the shared library (a gateway, a Makefile and a loader are
//generated.
files=['sci_cppfind.cxx'];
ilib_build('foo_old',['cppfind','sci_cppfind'],files,[]);
// load the shared library
`exec`_ loader.sce
// Small test to see if the function is actually working.
if cppfind("my very long string","long") <> 8 pause, end
if cppfind("my very long string","very") <> 3 pause, end
if cppfind("my very long string","short") <> -1 pause, end
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_f90');
`cd`_('example_ilib_build_f90');
sourcecode=['subroutine incrdoublef90(x,y)'
' implicit none'
' double precision, intent(in) :: x'
' double precision, intent(out) :: y'
' y=x+1'
'end subroutine incrdoublef90'];
`mputl`_(sourcecode,'incrdoublef90.f90');
libpath=`ilib_for_link`_('incrdoublef90','incrdoublef90.f90',[],'f');
`exec`_ loader.sce
n=1.;
m=`call`_("incrdoublef90",n,1,"d","out",[1,1],2,"d");
if `abs`_(m-2.)>%eps then pause,end
n=2.;
m=`call`_("incrdoublef90",n,1,"d","out",[1,1],2,"d");
if `abs`_(m-3.)>%eps then pause,end
`cd`_ TMPDIR;
`mkdir`_('example_ilib_build_cflag');
`cd`_('example_ilib_build_cflag');
csource = ['#include <stdlib.h>'
'#include <api_scilab.h>'
'#include <sciprint.h>'
''
'int sci_examplecflag(char *fname)'
'{'
''
'#ifdef __MYDEF_FOR_THIS_FUNCTION__'
'sciprint(""__MYDEF_FOR_THIS_FUNCTION__ detected !!!\n"");'
'#else'
'sciprint(""__MYDEF_FOR_THIS_FUNCTION__ not detected !!!\n"");'
'#endif'
''
' LhsVar(1) = 0;'
' return 0;'
'}'];
`mputl`_(csource, TMPDIR + '/example_ilib_build_cflag/sci_cflags.c');
//creating the shared library (a gateway, a Makefile and a loader are
//generated.)
files=['sci_cflags.c'];
// here we uses cflags argument and we define __MYDEF_FOR_THIS_FUNCTION__
ilib_build('gw_c_flags',['examplecflag','sci_examplecflag'], files, [], [], '', '-D__MYDEF_FOR_THIS_FUNCTION__');
// load the shared library
`exec`_ loader.sce;
//using the new primitive
examplecflag() // __MYDEF_FOR_THIS_FUNCTION__ detected !!!
`ulink`_();
`exec`_ cleaner.sce;
// and now
ilib_build('gw_c_flags',['examplecflag','sci_examplecflag'], files, []);
`exec`_ loader.sce;
examplecflag() // __MYDEF_FOR_THIS_FUNCTION__ not detected !!!
Version Description 5.4.0 This function no more accepts files with ”.o” or ”.obj” extensions as source files. .. _Full technical description of the incremental link / dynamic link: http://wiki.scilab.org/Full%20technical%20description%20of%20the%20incremental%20link .. _ilib_for_link: ilib_for_link.html .. _ilib_compile: ilib_compile.html .. _addinter: addinter.html .. _link: link.html .. _ilib_gen_loader: ilib_gen_loader.html .. _api_scilab: api_scilab.html .. _ilib_gen_Make: ilib_gen_Make.html .. _ilib_gen_gateway: ilib_gen_gateway.html