Hi Jürgen: Thank you for the additional information. I am doing a deep dive into a few things on macOS. (1) How to statically link libapl.so (2) How to link libapl.so so that addresses are resolved at load time - (dlopen and friends) (3) How to link libapl.so at run time (passing environment variable at execute time)
Why bother? Because there is insufficient documentation for GNU APL with examples. If I manage to complete these tasks then I can document them for posterity. I also have a few ideas for having a user interface other than Terminal (a.k.a. Command Line). Also I will try to understand if I need to change the file extension from .so to .dylib. That’s Apple’s dynamic library extension — typical Apple arrogance…. IMHO it should not be necessary…. the Unix linker is capable of sorting things out. Flashback: The last time I worked at this low a level was when I hacked mainframe IBM 360 OS’ and coded in Assembly and had to understand //DD… commands — back in the 60’s. Never needed to for Macintosh….or anyUnix for that matter. respect Peter On May 25, 2018, at 8:48 AM, Juergen Sauermann <[email protected]> wrote: > > Hi Peter, > > I am not familiar with the details of all file types, but it seems like your > understanding is correct. > > I should have added some more details in my last email: > > Say you have an application APP (your main() program) and a library LIB (in > our case libapl). > > If you link APP and LIB (at compile time) then the undefined symbols in APP > are matched against > the symbols defined in LIB and the undefined symbols in LIB are matched > against the symbols defined in APP. > There are two possible outcomes of the linking: > > 1. there are still undefined symbols left in either APP or in LIB, > 2. all symbols that were undefined before the linking are now resolved. > > Case 1 produces a linker error unless you tell the linker that you expect > remaining undefined symbols > (a so-called incremental link). An incremental link is kind of an > intermediate result that requires more files > to be linked to the intermediate result. > > Case 2 is the final result of zero or more incremental links. An executable > must not have undefined symbols, > so if a linker result is (supposed to be) an executable the the linker will > report an error. This is what happened > in you example: your APP has an undefined symbol init_libapl. This symbol is > undefined in APP and defined in LIB. > However, the fact that it is defined in LIB does not help you because you > only dlopen() LIB in APP (which happens later > at runtime) but you did not link LIB and APP. But the linker was not even > able to produce APP and therefor the fact > that LIB contains the undefined symbol (at runtime) does not satisfy the > linker at runtime. > > What you need to get your example running is the linker option -lapl. -lapl > is equivalent to -l apl and also to > its easier to understand long form --library=apl. It tells (by convention) > the linker to include the files libapl.a or > libapl.so (if present) in the linking of the object files given to the linker. > > If you link with -lapl, then the linker will resolve the undefined symbol > init_libapl at compile time (more precisely: at link > time) and dlopen()ing libapl does not do any good because we are in case 2 > already. > > Best regards, > /// Jürgen > > > On 05/24/2018 11:00 PM, Peter Teeson wrote: >> Although I've lived in the Apple Xcode world for the last many years, I am >> not afraid of the command line. >> So I’m trying to learn more about the way GNU APL is built from the command >> line using the autotools suite. >> In particular building GNU APL as a library using the —with-libapl >> configures option. >> >> I’ve run into some new file extensions in examining things and I would like >> confirmation that my understanding of their meaning: >> >> Difference Between PIC, .o, .a, .lo, .so, .po (Po), .tpo (.TPo), .plo (Plo), >> (.TPlo). >> Executive Summary >> PIC is position independent code >> .o is typically a non-PIC object file emitted by the compiler (before >> linker stage) >> When linked with an exe, the code will be included in the executable -- >> we bind at link time. >> .a is typically an archive library containing one or more .o files >> [non-PIC]. >> When linked with an exe, the particular "*.o" files in the archive will >> be inserted into the executable. >> .lo is generally a "library object" that contains PIC code whether >> manually compiled with gcc -fPIC or using libtool. >> .so files are "shared object" files. They contain PIC objects. >> .po (.Po) text files describing object files >> .tpo (.TPo) temporary text files describing object files >> .plo (.Plo) text file describing library object file >> .tplo (.TPlo) text file describing temporary library object >> >> Am I correct? >> >> Thanks & respect… >> >> Peter >> >>> On May 20, 2018, at 4:59 PM, Dirk Laurie <[email protected]> >>> <mailto:[email protected]> wrote: >>> 2018-05-20 21:44 GMT+02:00 Juergen Sauermann >>> <[email protected]> <mailto:[email protected]>: >>>> As far as I understand, there are two ways to link libapl with your >>>> application: >>>> >>>> 1. link it at compile time (with the -lapl linker option) or >>>> 2. dlopen() it at runtime (your approach). >>>> >>>> In case 2. the symbol init_libapl is NOT resolved by dlopen() but has to be >>>> resolved via dlsym() and >>>> then called with the return value of dlsym(). There might also exist some >>>> (usually platform specific) linker options that >>>> cause dlopen() to resolve all symbols provided in a shared library >>>> automatically, but I don't know. >>>> >>>> I should mention that libapl is mainly a work of Dirk Laurie, I suppose he >>>> does not use dlopen(), but uses approach 1. >>>> Maybe Dirk can give you some more hints about how to use libapl. >>> I did this three years ago, using SVN 570 of GNU APL. In an ideal >>> world, I would have checked after every SVN update that my application >>> still works. In the real world, I have not touched it since and cannot >>> remember much. :-( >>> >>> I currently have SVN 1048. When I tried it my application [1] (which >>> runs GNU APL in parallel with Lua) just now, the Lua 5.2 version that >>> I made on 29 May 2015 still works in a simple test. >>> >>> $ lua -l gnuapl >>> Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio >>> …/gnuapl$ lua5.2 -l gnuapl >>> Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio >>>> =gnuapl.exec"4 4⍴⍳16" >>> 1 2 3 4 >>> 5 6 7 8 >>> 9 10 11 12 >>> 13 14 15 16 >>> This seems to confirm that there is nothing wrong with libapl.so. >>> >>> Unfortunately I have no simple C main program, since everything runs >>> through Lua. In particular, Lua's 'package.loadlib' function is used >>> to load the current libapl.so. The code for that function is way above >>> my code-reading ability. >>> >>> Sorry that I can't offer more help. >>> >>> -- Dirk >>> >>> [1] Those that are reasonably fluent in Lua and its C API can try it >>> out: https://github.com/dlaurie/lua-gnuapl >>> <https://github.com/dlaurie/lua-gnuapl> >> >
