ilib_build

utility for shared library management

Calling Sequence

ilib_build(lib_name,table,files,libs [,makename,ldflags,cflags,fflags,ismex, cc])

Arguments

:lib_name a character string, the generic name of the library without
path and extension.
: :table 2 column string matrix giving the table of pairs ‘scilab-
name’, ‘interface name’
: :files string matrix giving source files needed for shared library
creation. Since Scilab 5.3.1, object files are deprecated.
: :libs string matrix giving extra libraries needed for shared library
creation
: :makename character string. The path of the Makefile file without
extension. This parameter is useless since Scilab 5.0. Default value to use: []. A warning will be displayed in Scilab 5.3 if you use another value that the default.
: :ldflags,cflags,fflags character strings to provide options for the
loader, the C compiler and the Fortran compiler.
: :ismex Internal variable to specify if we are working with mex or
not.

: :cc Provide the name of the C compiler. :

Description

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.

Examples (C code)

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

Examples (C code - previous Scilab API < 5.2)

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

Examples (C++ code)

`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

Examples (C++ code - previous Scilab API < 5.2)

`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

Examples (Fortran 90 code)

`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

Example: How to use cflags arguments

`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 !!!

See Also

History

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