yeah I apologise for the wrong example , LibC utilises the enviroment/system variables.

Generally speaking all OSes have a PATH variable that defines the places where common libraries and tools are to be found. If you are on windows you can type in the command prompt , "PATH", in Linux and MacOS is "$PATH" . You can add your path in Windows using the system variables dialog window, in MacOS and Linux it usually happens via .bash-config file that setups the path but I am not so sure.

The easiest way is to do something like macModuleName does in the LGitLibrary class the code is

macModuleName
������ | pluginDir |
������ pluginDir := Smalltalk vm binary parent / 'Plugins'.
������ #('libgit2.dylib' 'libgit2.0.dylib')
������ ������ detect: [ :each | (pluginDir / each) exists ]
������ ������ ifFound: [ :libName | ^ libName ].

������ self error: 'Module not found.'

Hope that helps

On Wed, Oct 17, 2018 at 12:54 PM Michel Onoff <michel.onoff@web.de> wrote:
Hi Dimitris,

thanks for the long explanation.

As you can see from my example, I build the library with the
�� �� ��-undefined dynamic_lookup
flag to clang, so this should be compatible with your (3) option if I
understand you correctly. Compiling/linking this way should allow the
use of dlopen(3) from UFFI during the execution of Pharo code, exactly
as I try to simulate with my small test programs.

Pharo complains about not being able to load the module (the library),
even if it appears in the Pharo main folder. It does not report whether
it cannot find it or if it cannot bind it using dlopen(3).

Moreover, it is unclear to me how Pharo interacts with DYLD_LIBRARY_PATH
(on macOS) or LD_LIBRARY_PATH (on Linux) environment variables if they
are set.

In other words, Where does it search for libraries?



Anyway, I'll try your script on cmake.


Regards
MO




for use with dlopen()

On 2018-10-17 11:32, Dimitris Chloupis wrote:
> I advice first of all the use of CMake , you can thank me later.
>
> CMake if you are not aware is the standard build system for C/C++ , it
> makes it super easy to build and compile projects so you dont have to do
> what you are doing, call the compiler and pass the inifite amount of
> compiler flags that it needs.
>
> To understand how to build a library you have to understand first what a
> library is.
>
> Libraries used by Pharo are known as either Shared Libraries on Macos
> (dylib) and Linux (so) but Dynamically Linked Libraries on Windows
> (DLLs). They are executables designed to be called from another
> executable (this includes another library as well).
>
> Those libraries operate in 3 modes
> 1) Static linking
> 2) semi dynamic linking
> 3) dynamic linking
>
> (1) may come as suprise but yes those libraries can be linked to the
> executable and build inside the exrecutable. But in our case we done
> want that because it would mean to rebuild the VM.
> (2) is not what we want either because eventhough it builds the library
> independently generating the usual exetension files I mentioned above it
> includes its symbole table in the executable so you wont have to do what
> UFFI does, wrap or map your code to those library functions. The
> equivelant for Pharo would mean that we would not need UFFI at all but
> we do need to rebuld the VM to include ths symbol table. The symbole
> table basically includes the name of the functions, their signatures
> (type of arguments) and their corresponing adresses in memory needed to
> access them.
>
> (3) is what UFFI does, in that cause the executable is not affected at
> all so you dont need to to rebuild the vm. But you do need to know where
> to find the library , to access its symbol table and make sure the
> variables your executable uses match the type and signature in the
> symbol table or else the executable wont able to locate and correctly
> call these functions. Of course libraries can contain structs and global
> variables as well but the concept is the same. Now this messy part is
> handled by the UFFI although barely because it still needs from you to
> provide the correct signature to the function.
>
> I am giving you the long version because you have to make sure you build
> you library with (3) way and not (2). (1) can be easily avoid but it is
> easy to mix (2) and (3). From there on its easy , locating the library
> is provided as a string returned by a method , see how UFFI utilises
> LibC for example and from there on you just convert the signatures to
> symbol arrays as described by the UFFI tutorials.
>
> For cmake you only need to use -> add_library(libraryname MODULE ${SRC}
> ). You can find a CmakeList.txt file that I use here
> https://gist.github.com/kilon/ff4b973bdeb3b0c0253ac373a4b2506a
>
> If you are wondering why its so big, its because the project I link
> against is huge and because I move the DLL to its build folder instead
> of building it in the same folder as my source code. It CMake's why of
> keeping things seperate and organised. Observe also that I use dll
> exension for Windows and MacOS, The extensions plays no role so I
> decided to go for the same extension to save time although usually its
> preferable go for the standard extensions.
>
> Beware that if your library uses any external code even parts of the C
> standard library those will have to be included , usually you need only
> the header files, which is what SET INC is doing in my example, while
> SET SRC includes only the library files. The inclusion of headers is
> super important because they are used to build the symbol table which is
> the most important part of the library. Without a correctly build symbol
> table the library is useless even when used from C/C++.
>
> On Wed, Oct 17, 2018 at 11:09 AM Michel Onoff <michel.onoff@web.de
> <mailto:michel.onoff@web.de>> wrote:
>
>�� �� ��Hello,
>
>�� �� ��I've made some attempts to use the Pharo FFI. I've gone through the
>�� �� ��documentation [1] and tried some examples.
>
>�� �� ��While the documentation is quite clear about using external libraries
>�� �� ��from Pharo, it lacks details on how to build own libraries to be used
>�� �� ��from Pharo.
>
>�� �� ��Specifically, I'm trying to build on all supported platforms, namely
>�� �� ��macOS, Windows and Linux. Currently I've got Linux and Windows under
>�� �� ��control, but I cannot find a systematic way to build on macOS.
>
>�� �� ��Here's an example for a library that I can use from a small test
>�� �� ��program
>�� �� ��but not from Pharo. Unfortunately, the diagnostic on Pharo is not
>�� �� ��detailed: it simply reports that it cannot load the module.
>
>
>�� �� ��clang -I <include-path> -O3 -c <source-path>
>�� �� ��...
>�� �� ��clang -dynamiclib <object-files> -o lib<name>.dylib -undefined
>�� �� ��dynamic_lookup
>
>�� �� ��cp lib<name>.dylib <pharo-folder>
>
>
>�� �� ��Is there good documentation about how to correctly build libraries so
>�� �� ��that they can be used from Pharo?
>
>�� �� ��Alternatively, are there details on how Pharo FFI searches for
>�� �� ��libraries
>�� �� ��and links them in the Pharo process?
>
>
>�� �� ��Regards
>�� �� ��MO
>
>�� �� ��----
>
>�� �� ��[1] https://files.pharo.org/books-pdfs/booklet-uFFI/UFFIDRAFT.pdf
>
>