Linux Island program and "undefined reference to" errors

I’m attempting to write an Oxygene Linux Island app that calls functions in a C shared library. I’ve created libgpio.fx successfully using an import project. But when I attempt to use libgpio.fx, I get the following errors:

C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello>make
"C:/Program Files (x86)/RemObjects Software/Elements/Bin/EBuild" "test_hello.elements" --configuration:Release
RemObjects EBuild. An open source build engine for Elements and beyond.
Copyright RemObjects Software 2016-2019. All Rights Reserved. Created by marc hoffman.
Version 10.0.0.2437 (develop) built on bajor, 20190906-114556. Commit e1dfdd2.

   Reference 'libgpio' was resolved to 'C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libgpio.fx' via 'HintPath' for target 'Island-Linux'.
   Reference 'libgpio' was resolved to 'C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libgpio.fx' for target 'Island-Linux' (x86_64).
   Reference 'rtl' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\Island\SDKs\Linux\Ubuntu 2.19\x86_64\rtl.fx' for target 'Island-Linux'.
   Reference 'rtl' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\Island\SDKs\Linux\Ubuntu 2.19\x86_64\rtl.fx' for target 'Island-Linux' (x86_64).
   Reference 'gc' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\Island\SDKs\Linux\Ubuntu 2.19\x86_64\gc.fx' for target 'Island-Linux'.
   Reference 'gc' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\Island\SDKs\Linux\Ubuntu 2.19\x86_64\gc.fx' for target 'Island-Linux' (x86_64).
   Reference 'Island' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\References\Island\Ubuntu\x86_64\Island.fx' for target 'Island-Linux'.
   Reference 'Island' was resolved to 'C:\Program Files (x86)\RemObjects Software\Elements\References\Island\Ubuntu\x86_64\Island.fx' for target 'Island-Linux' (x86_64).
   RemObjects Elements (Oxygene, C#, Swift and Java) Compiler for .NET, Cocoa, Java and Island.
   Version 10.0.0.2437 (develop) built on bajor, 20190906-114556. Commit e1dfdd2.
   Copyright 2003-2019 RemObjects Software, LLC. All rights reserved.
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to strncpy
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to __xpg_strerror_r
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to __h_errno_location
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to inet_ntoa
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to system
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to tcflush
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to snprintf
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to lseek
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to __assert_fail
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to htonl
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to epoll_ctl
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to gethostbyname2
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to getpwnam
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to fprintf
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to syslog
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to daemon
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to cfmakeraw
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to ntohs
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to epoll_wait
E: C:\Users\pmunts\src\experimental\elements\linux\programs\test_hello\libsimpleio.so: undefined reference to poll
E: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
   Project 'test_hello' failed to build.
   Solution 'test_hello' failed to build all projects.
C:/Users/pmunts/src/libsimpleio/elements/include/elements.mk:43: recipe for target 'elements_mk_build' failed
make: *** [elements_mk_build] Error 1

These appear to be all of the symbols in glibc that the code in the shared library references.

The application project including the .fx and .so files is attached.test_hello.zip (29.1 KB)

Addendum: The above is from trying to build on Windows.

Building on Linux yields a completely different error; perhaps it is getting further along:

pmunts@builder:~/src/experimental/elements/linux/programs/test_hello$ make
"/usr/local/bin/ebuild" "test_hello.elements" --configuration:Release
RemObjects EBuild. An open source build engine for Elements and beyond.
Copyright RemObjects Software 2016-2019. All Rights Reserved. Created by marc hoffman.
Version 10.0.0.2437 (develop) built on bajor, 20190906-114556. Commit e1dfdd2.

   Reference 'libgpio' was resolved to '/home/pmunts/src/experimental/elements/linux/bindings/libgpio.fx' via 'HintPath' for target 'Island-Linux'.
   Reference 'libgpio' was resolved to '/home/pmunts/src/experimental/elements/linux/bindings/libgpio.fx' for target 'Island-Linux' (x86_64).
   Reference 'rtl' was resolved to '/usr/local/lib/elements/Island SDKs/Linux/Ubuntu 2.19/x86_64/rtl.fx' for target 'Island-Linux'.
   Reference 'rtl' was resolved to '/usr/local/lib/elements/Island SDKs/Linux/Ubuntu 2.19/x86_64/rtl.fx' for target 'Island-Linux' (x86_64).
   Reference 'gc' was resolved to '/usr/local/lib/elements/Island SDKs/Linux/Ubuntu 2.19/x86_64/gc.fx' for target 'Island-Linux'.
   Reference 'gc' was resolved to '/usr/local/lib/elements/Island SDKs/Linux/Ubuntu 2.19/x86_64/gc.fx' for target 'Island-Linux' (x86_64).
   Reference 'Island' was resolved to '/usr/local/lib/elements/References/Island/Ubuntu/x86_64/Island.fx' for target 'Island-Linux'.
   Reference 'Island' was resolved to '/usr/local/lib/elements/References/Island/Ubuntu/x86_64/Island.fx' for target 'Island-Linux' (x86_64).
   RemObjects Elements (Oxygene, C#, Swift and Java) Compiler for .NET, Cocoa, Java and Island.
   Version 10.0.0.2437 (develop) built on bajor, 20190906-114556. Commit e1dfdd2.
   Copyright 2003-2019 RemObjects Software, LLC. All rights reserved.
E:
Internal error: System.DllNotFoundException: RemObjects.Elements.LLVM.dll assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) LLVM.Interop.LLVMInterop.LLVMInitializeAll()
  at RemObjects.Elements.Island.IslandOutput..cctor () [0x001a9] in <a364d32ff0b94ca4803a6ba08ed6eb73>:0
   Project 'test_hello' failed to build.
   Solution 'test_hello' failed to build all projects.
make: *** [/usr/local/share/libsimpleio/elements/include/elements.mk:43: elements_mk_build] Error 1

On Linux you’ll need to install the llvm .so file to be able to compile. We ship that as libRemObjects.Elements.LLVM.so but it needs to be installed to /usr/lib or the library search path needs to be adjusted to it. Now for the actual issue:

What you need to do is add something like this to the import json of your fx file:

"ImportDefs": [
		{"Name": "open64", "Library": "libpthread.so.0"}, 
		{"Name": "localtime", "Library": "libc.so.6"}, 
		{"Name": "access", "Library": "libc.so.6"}, 
		{"Name": "getcwd", "Library": "libc.so.6"}, 
		{"Name": "fchmod", "Library": "libc.so.6"}, 
		{"Name": "unlink", "Library": "libc.so.6"}, 
		{"Name": "fchown", "Library": "libc.so.6"}, 
		{"Name": "geteuid", "Library": "libc.so.6"}, 
		{"Name": "mmap64", "Library": "libc.so.6"}, 
		{"Name": "munmap", "Library": "libc.so.6"}, 
		{"Name": "mremap", "Library": "libc.so.6"}, 
		{"Name": "readlink", "Library": "libc.so.6"}, 
		{"Name": "pthread_mutexattr_destroy", "Library": "libpthread.so.0"}, 
		{"Name": "lseek64", "Library": "libpthread.so.0"}, 
		{"Name": "sysconf", "Library": "libc.so.6"}, 
		{"Name": "utimes", "Library": "libc.so.6"}, 
		{"Name": "getpid", "Library": "libc.so.6"}, 
		{"Name": "memcmp", "Library": "libc.so.6"}, 
		{"Name": "strncmp", "Library": "libc.so.6"}, 
		{"Name": "getpid", "Library": "libc.so.6"}, 
		{"Name": "gettimeofday", "Library": "libc.so.6"}, 
		{"Name": "strcmp", "Library": "libc.so.6"}, 
		{"Name": "wmemchr", "Library": "libc.so.6"}
  ]

This defines “where” these functions are. The problem is that the compiler doesn’t know what a .so references, so you end up with missing symbols. This tells the importer that when looking for a symbol where it is.

I’m planning on making this easier, and can help you if you send me the json file if needed.

I can create the JSON file you suggested with shell scripts. But I can’t find any information about how to feed it into the .fx project. Or should it be fed to the application program project?

I’m building libgpio.fx using an import project: libgpio.zip (2.9 KB)

FTR, the install.sh script should handle that for you. If it does not, that would be a bug, I’d appreciate if you could send me the output of running install.sh so that I can investigate this part.

This is the current script:

elif [ "$platform" == 'Linux' ]; then
	sudo mkdir -p /usr/lib/
	sudo cp libRemObjects.Elements.LLVM.so /usr/lib/
	...
fi

does the script print out "Detected platform: Linux" or "Detected unsupported platform 'x" (ands if so, what does it show for x?)

Indeed, Carlo seems to have mixed ups two ways to do import, an older path, and import projects (which do not use their json format anymore). I’ll ask Carlo to clarify what needs to be done here, in the morning.

OK, I’ve just done a fresh install on Debian 10 (Buster) Linux. Normally I install Elements to /usr/local/lib/elements/ but for this test I installed it to $HOME/elements.

Here is my install procedure (please note the two comments):

mkdir -p $HOME/elements
unzip 'RemObjects Elements - Mac and Linux Zip Distro - 10.0.0.2437.zip' -d $HOME/elements
cd $HOME/elements
# zip does not preserve executable permission
chmod +x *.sh *.so *.dylib lld*
./install.sh 2>&1 | tee $HOME/install.out
# install.sh should run ldconfig after installing .so
sudo ldconfig

Here is the output from install.sh:

Detected platform: Linux
Touching files
Clearing GAC
GACing new dlls
Registering CodeDom
RemObjects Elements CodeDom Installer

RemObjects Elements Version is 10.0.0.2437
File /usr/lib/mono/4.5/CONFIG/machine.config does not exist.
WARNING: The runtime version supported by this application is unavailable.
Using default runtime: v4.0.30319
Copying LLVM
Done.

The shared library and ebuild are installed as expected (but note that the ownership of ebuild is wrong):

pmunts@builder:~$ ls -lrt /usr/lib | tail -n 1
-rwxr-xr-x   1 root root 123222312 Sep 26 13:29 libRemObjects.Elements.LLVM.so
pmunts@builder:~$ ls -lrt /usr/local/bin | tail -n 1
-rwxr-xr-x 1 pmunts pmunts     45 Sep 26 13:29 ebuild
pmunts@builder:~$ 

Next I tried building one of my Oxygene .Net Core applications. It built fine. But building the Linux Island application I’m currently working on still fails:

   RemObjects Elements (Oxygene, C#, Swift and Java) Compiler for .NET, Cocoa, Java and Island.
   Version 10.0.0.2437 (develop) built on bajor, 20190906-114556. Commit e1dfdd2.
   Copyright 2003-2019 RemObjects Software, LLC. All rights reserved.
E: Internal error: System.DllNotFoundException: RemObjects.Elements.LLVM.dll assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) LLVM.Interop.LLVMInterop.LLVMInitializeAll()
  at RemObjects.Elements.Island.IslandOutput..cctor () [0x001a9] in <a364d32ff0b94ca4803a6ba08ed6eb73>:0 
   Project 'test_hello' failed to build.
   Solution 'test_hello' failed to build all projects.

I’ve thought about some patches for install.sh. Maybe I’ll open a new topic for that.

1 Like

Thanks. I’ll have a look at both in the am. So the .so is in the right place now, but it still fails to load?

Yeah sorry I was confused about the project format you used. Can you use this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProjectGuid>{6E2A5997-1517-4060-A0B6-5096595C7653}</ProjectGuid>
    <OutputType>Import</OutputType>
    <RootNamespace>libgpio</RootNamespace>
    <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
    <Mode>Island</Mode>
    <SubMode>Linux</SubMode>
    <Architecture>x86_64;armv6;aarch64</Architecture>
    <ImportCodeGen>Oxygene</ImportCodeGen>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <OutputPath>.\Bin\Debug</OutputPath>
    <EnableAsserts>True</EnableAsserts>
    <Optimize>False</Optimize>
    <GenerateDebugInfo>True</GenerateDebugInfo>
    <DefineConstants>DEBUG;TRACE;</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <OutputPath>.\Bin\Release</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <ImportHeader Include="libgpio.h" />
    <SymbolMapping Include="libsimpleio.so">
        <SymbolNames>*</SymbolNames>
    </SymbolMapping>
  </ItemGroup>
  
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.targets" />
</Project>

So what happens is that somehow, the LLVM linker tries to resolve the dependencies of libsimpleio.so too (which are in libc and other places), but really all I want it to do is use libsimplio.so for the references from this project. We don’t deploy Linux’ libc, instead we pretend it’s there by writing out a dummy .so file that has the things we need, without the rest. So the linker can’t resolve the extra stuff libsimplio.so wants. Now above change works the other way around, it doesn’t hard link to that so file, instead it creates a dummy import for it, with no dependencies. This seems to work:


  0x0000000000000001 NEEDED               SharedLibrary (libsimpleio.so)
  0x0000000000000001 NEEDED               SharedLibrary (libdl.so.2)
  0x0000000000000001 NEEDED               SharedLibrary (libm.so.6)
  0x0000000000000001 NEEDED               SharedLibrary (libgcc_s.so.1)
  0x0000000000000001 NEEDED               SharedLibrary (librt.so.1)
  0x0000000000000001 NEEDED               SharedLibrary (libc.so.6)
  0x0000000000000001 NEEDED               SharedLibrary (libpthread.so.0)

That seems to work. I had seen the SymbolMapping tag but for some reason I thought I had to use ImportLinkNames instead. And now I don’t have to have libsimpleio.so present to build the application program.

What happens if I want to use two shared libraries, like libsimpleio.so and libfoo.so?

From one fx? Symbolmap does both exact and masked symbols. So say gpio* would cover all gpio symbols. Exact matches take precedence over masks