BUG - ProteaAudio with Lua does not work - linux

Any idea why i cant use or cant build in Lua the ProTeaAudio ?
1) Exist
[root#example ~]# yum install lua-devel
Loaded plugins: presto, refresh-packagekit
Setting up Install Process
Package lua-devel-5.1.4-4.fc12.i686 already installed and latest version
Nothing to do
2) get failed to build the RtAudio
[sun#example proteaAudio_src_090204]$ make
g++ -O2 -Wall -DHAVE_GETTIMEOFDAY -D__LINUX_ALSA__ -Irtaudio -Irtaudio/include -I../lua/src -I../archive/baseCode/include -c rtaudio/RtAudio.cpp -o rtaudio/RtAudio.o
rtaudio/RtAudio.cpp:365: error: no ‘unsigned int RtApi::getStreamSampleRate()’ member function declared in class ‘RtApi’
rtaudio/RtAudio.cpp: In member function ‘virtual bool RtApiAlsa::probeDeviceOpen(unsigned int, RtApi::StreamMode, unsigned int, unsigned int, unsigned int, RtAudioFormat, unsigned int*, RtAudio::StreamOptions*)’:
rtaudio/RtAudio.cpp:5835: error: ‘RTAUDIO_SCHEDULE_REALTIME’ was not declared in this scope
rtaudio/RtAudio.cpp:5837: error: ‘struct RtAudio::StreamOptions’ has no member named ‘priority’
make: *** [rtaudio/RtAudio.o] Error 1
[sun#example proteaAudio_src_090204]$
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require("proAudioRt");
stdin:1: module 'proAudioRt' not found:
no field package.preload['proAudioRt']
no file './proAudioRt.lua'
no file '/usr/share/lua/5.1/proAudioRt.lua'
no file '/usr/share/lua/5.1/proAudioRt/init.lua'
no file '/usr/lib/lua/5.1/proAudioRt.lua'
no file '/usr/lib/lua/5.1/proAudioRt/init.lua'
no file './proAudioRt.so'
no file '/usr/lib/lua/5.1/proAudioRt.so'
no file '/usr/lib/lua/5.1/loadall.so'
stack traceback:
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?

Lua is trying to tell you that it cannot find an implementation of the module "proAudioRt" which it tried to find in a variety of places. The first block of places are various attempts at loading an implementation in Lua, then there are a few tries at various shared object files that might have contained the module. Since none of the places work, require fails.
None worked, because you haven't actually built a .so containing the module.
You need to get all of the compile and link errors to clear up so that you build proAudioRt.so. Note that for that to actually contain a Lua module, it must have a C callable entry point named luaopen_proAudioRt(), with the signature
LUALIB_API int luaopen_proAudioRt(lua_State *L);
That function is expected to construct the module's table, supplying it with members containing the functions of the module. The function luaL_register() is handy for this.
The Lua users wiki has a section on binding to Lua that should be helpful as well.

Related

When linking a shared library on linux, are all modules included?

I'm porting a system of apps from AIX to linux, and all of those apps include a single shared library. I've got the shared library building on as a linux .so now - and I see at least one post here that describes how to specify what's exported from a shared library (as AIX does via a .exp file).
Just one silly question, though. On AIX, if a module in a shared library is not referenced by anything in the app that's linking to it, it is ignored by the linker. That doesn't seem to be the case on linux - but I want to make sure.
While testing my linux shared library, I left out one module with dependencies I wasn't ready to deal with yet (or more accurately, I provided a substitute module with dummy functions for all the entry points to that module, thinking that would allow it to link). So far, so good. But when I attempted to link that shared library into a trivial test app, the linker reported unresolved symbols for stuff referenced by another shared library module that is itself only referenced from within the module I replaced with dummies. I.e., I would have expeceted that module to simply be ignored...
In other words, this module is being considered by the linker as part of the final application even though nothing in the app references it. I tried the same experiment on AIX (replacing the same module with dummies and attempting to link a trivial app there). No complaints.
So, The AIX linker only attempts to resolve shared library module dependencies if those modules themselves are explicitly called in from the application. But the linux linker attempts to resolve dependencies for all shared library modules whether they're called in from the application or not.
Is this true? And if so, is there any way to override that behavior? Ultimately, when I port everything, all of the dependencies will resolve. But for now, it's hard to leave something out - even if it's not referenced...
Here's a minimal case:
main.c contains function main(), which calls function one().
one.c contains function one(), which does nothing.
two.c contains function two(), which calls function three().
There is no function three(), but libshared.so is built from
modules one.c and two.c. Program main is built from main.c and
links in libshared.so.
The linker needs to resolve function one(), which is in the shared
library. But that's all main.c requires. Still, function two() in
the library references function three(), which doesn't exist.
The linker will complain about the undefined symbol 'three', even
though program main doesn't need it.
On AIX the linker will not complain and everything will work.
main.c:
#include <stdio.h>
int one();
int main()
{
one();
}
one.c:
#include <stdio.h>
int one()
{
return 1;
}
two.c:
#include <stdio.h>
int three();
int two()
{
return three();
}
build libshared.so with modules one.c and two.c:
gcc -fPIC -shared one.c two.c -o libshared.so
Attempt to build main from main.c and libshared.so:
gcc main.c -o main -L. -lshared
./libshared.so: undefined reference to `three'
collect2: error: ld returned 1 exit status
The linker reports an undefined reference to 'three',
which is referenced from two() - but main() doesn't ever call two().
The actual answer: shared libraries are in fact shared objects: they are treated as a single object, not as a *.a library.
This shows that Linux (meaning: glibc/gcc/gold/ld) and AIX have different concepts regarding shared objects.
In Linux, when you link an executable, ld/gold checks the dependencies of the used shared objects as well -- Aix linker doesn't: it assumes that the shared objects are to be used as they are, their dependencies aren't part of the current linking. (At least this is the default behaviour.)
Here is a summary of my tests:
+----------------+--------------------+-------------------------------+
| | AIX | linux |
+----------------+--------------------+-------------------------------+
| libshared.so | only with option | yes |
| can be created | -Wl,-berok | |
+----------------+--------------------+-------------------------------+
| main | yes | only with option |
| can be created | | -Wl,--allow-shlib-undefined |
+----------------+--------------------+-------------------------------+
Note: My random thoughts regarding AIX and linking: http://lzsiga.users.sourceforge.net/aix-linking.html
By default the GNU binutils linker, ld on
Linux requires a symbol ref to be defined by some input file (i.e. object file or
shared library) in the linkage if ref is referenced by the definition of any
symbol def in any input file that the linkage needs. It doesn't matter whether def is referenced in turn.
Your program linkage needs libshared.so. libshared.so defines two, which refers to three,
so three must be defined.
You can countermand this default behaviour to tolerate undefined references in shared libraries
(but not in object files) as follows:
$ gcc main.c -o main -L. -lshared -Wl,--allow-shlib-undefined
--allow-shlib-undefined is documented in the ld manual
The notion of module in your language corresponds to translation unit at the
compilation level and object file at the linkage level. It might be helpful to
appreciate that an object file input to the linkage of a ELF program or shared library
has no distinct existence in the program or shared library. It is cut into
pieces and scattered around. So there is no sense in which it would be possible
for a linkage:
$ gcc main.c -o main -L. -lshared ...
to ignore the unreferenced module two.(c|o) within
libshared.so. There is no such thing. If that linkage did not need any
definition provided by libshared.so then it would ignore the shared library
altogether1. If it needs the shared library, then by default its references
must be resolved.
[1] That is, on Debian-clan systems where gcc is built to invoke ld with the --as-needed option
by default. On Redhat-clan systems GCC by default links shared libraries if they are input, needed or not.

Crypto++ causes undefined reference in Qt Creator, but not in code::blocks

Nearly every function from Crypto++ produces undefined reference in Qt Creator, code::blocks however runs just great.
LIBS+= -lcryptopp
in .pro file seems to work as I can include needed files and declare variables unless constructor is overloaded.
For example
CryptoPP::Integer integer;
std::string str=CryptoPP::IntToString(integer, 10);
Throws
.../main.cpp:54: undefined reference to `std::string CryptoPP::IntToString<CryptoPP::Integer>(CryptoPP::Integer, unsigned int)'
collect2: error: ld returned 1 exit status
make: *** [PDBM] Error 1
07:10:21: The process "/usr/bin/make" exited with code 2.
cryptest.pro
Makefile
full rebuild //sorry, stackoverflow wants those links to be a code
/usr/lib/ contains libcrypto++.a, libcrypto++.so, libcryptopp.so and link to libcrypto++.a named libcryptopp.a
New findings: I have tried to compile this library before and now my project folder has all the .h and .cpp files in cryptopp folder. To provide all the code without showing the code new project has been created and more errors appeared:
In file included from /usr/include/cryptopp/secblock.h:7:0,
from /usr/include/cryptopp/integer.h:7,
from ../cryptest/main.cpp:7:
/usr/include/cryptopp/misc.h: In instantiation of ‘std::string CryptoPP::IntToString(T, unsigned int) [with T = CryptoPP::Integer; std::string = std::basic_string<char>]’:
../cryptest/main.cpp:54:54: required from here
/usr/include/cryptopp/misc.h:424:58: error: invalid cast from type ‘CryptoPP::Integer’ to type ‘char’
result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
^
Makefile:1113: recipe for target 'main.o' failed
Which means that cryptopp has been using those new .h files. So it is not only a problem with linker as I previously thought.
I'm on Ubuntu 16.04, using Qt 5.8 and Crypto++ from repository.
-lcryptopp
This option simply tells your linker that you want to link to a shared library called libcryptopp.so. However, it does not tell your linker where to find the shared library.
You must specify the folder which contains the developer's copy of the library, using the -L option. For example, if the library is in /usr/lib, then write this:
LIBS += -L/usr/lib/ -lcryptopp

Visual C++ linker complaining about the absence of a symbol that is not absent

In short: on Visual C++ 2015, I get a linker error complaining about the absence of symbols that are present in the .lib file I link against.
In long: While compiling-and-liking some program from the command line with cl.exe I get the following as the first of many errors:
main.obj : error LNK2001: unresolved external symbol "protected: static struct wxEventTable const wxApp::sm_eventTable" (?sm_eventTable#wxApp##1UwxEventTable##B)
AFAIK, this long line says that my main.obj refers to a function to which a symbol ?sm_eventTable#wxApp##1UwxEventTable##B is associated, but that the linker could not find this symbol in the (long) list of libs that I provided on the command line.
I compile in /MD mode. Don't know if it helps, hurts, or has no importance here.
One of the files I link with is wxmsw31u_core.lib and doing
dumpbin /headers wxmsw31u_core.lib > here.txt
gives a long file containting the following
Version : 0
Machine : 8664 (x64)
TimeDateStamp: 56D46194 Mon Feb 29 16:19:48 2016
SizeOfData : 00000045
DLL name : wxmsw310u_core_vc140_x64.dll
Symbol name : ?sm_eventTable#wxApp##1UwxEventTable##B (protected: static struct wxEventTable const wxApp::sm_eventTable)
Type : data
Name type : name
Hint : 14083
Name : ?sm_eventTable#wxApp##1UwxEventTable##B
From this I infer that wxmsw31u_core.lib this is an "import library" : in other words that means that this lib does not contain the code but just refers to the dll file wxmsw310u_core_vc140_x64.dll that actually contains the code.
The latter wxmsw310u_core_vc140_x64.dll file indeed mentions ?sm_eventTable#wxApp##1UwxEventTable##B as I checked:
dumpbin /EXPORTS wxmsw310u_core_vc140_x64.dll > here2.txt
gave
14084 3703 0057F008 ?sm_eventTable#wxApp##1UwxEventTable##B = ?sm_eventTable#wxApp##1UwxEventTable##B (protected: static struct wxEventTable const wxApp::sm_eventTable)
I note that the first number is equal to the hint of the previous header plus one. I suppose this is normal?
I took the time to check the DLL as above but AFAIK, the DLL is not required in the linking process (it is required when you call the .exe that is produced).
All in all, it seems everything is there and it should link, so I am at a loss to determine what's wrong here.
Edit
I partially solved the problem by compiling myself the libary instead of using the compiled binaires for Windows provided by wxWidgets: I can now compile my program and all is well.
Well, not all: the initial question remains. I had a situation where I tried to link an obj with a lib to get an exe, the obj refers to a symbol whose mangled name is present verbatim in the lib, the linker does load the obj and lib (confirmed using /VERBOSE), yet the linker refuses to consider the symbol as "resolved". Why?
I'll create a new question where I'll ask for explanations about the conditions to be resolved.
AFAIK, this long line says that my main.obj refers to a function to which a symbol ?
Yes, linker is not able to find sm_eventTable#wxApp##1UwxEventTable##B on your paths specified.
Check that you have properly setup Additional Library Path parameter and that target platform of your application is /Machine:X64

crt1.o: In function `_start': - undefined reference to `main' in Linux

I am porting an application from Solaris to Linux
The object files which are linked do not have a main() defined. But compilation and linking is done properly in Solaris and executable is generated. In Linux I get this error
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
My problem is, I cannot include new .c/.o files since its a huge application and has been running for years. How can I get rid of this error?
Code extractes of makefile:
RPCAPPN = api
LINK = cc
$(RPCAPPN)_server: $(RPCAPIOBJ)
$(LINK) -g $(RPCAPIOBJ) -o $(RPCAPPN)_server $(IDALIBS) $(LIBS) $(ORALIBS) $(COMMONLIB) $(LIBAPI) $(CCLIB) $(THREADLIB) $(DBSERVERLIB) $(ENCLIB)
Try adding -nostartfiles to your linker options, i.e.
$(LINK) -nostartfiles -g ...
From the gcc documentation:
-nostartfiles
Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used.
This causes crt1.o not to be linked (it's normally linked by default) - normally only used when you implement your own _start code.
-shared link option must be used when you compile a .so
The issue for me was, I by mistake put int main() in a namespace. Make sure don't do that otherwise you will get this annoying link error.
Hope this helps anyone :)
I had similar result when trying to build a new test project with boost, and it turned out that I was missing one declaration :
#define BOOST_TEST_MODULE <yourtestName>
I had this same problem when creating my c project, and I forgot to save my main.c file, so there was no main function.
I had a similar result when compiling a Fortran program that had C++ components linked in. In my case, CMake failed to detect that Fortran should be used for the final linking. The messages returned by make then ended with
[100%] Linking CXX executable myprogram
/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
make[3]: *** [myprogram] Error 1
make[2]: *** [CMakeFiles/myprogram.dir/all] Error 2
make[1]: *** [CMakeFiles/myprogram.dir/rule] Error 2
make: *** [myprogram] Error 2
The solution was to add
set_target_properties(myprogram PROPERTIES LINKER_LANGUAGE Fortran)
to the CMakeLists.txt, so that make prints out:
[100%] Linking Fortran executable myprogram
[100%] Built target myprogram
I had the same issue with a large CMake project, after I moved some functions from one code file to another. I deleted the build folder, recreated it and rebuilt. Then it worked.
Generally, with suddenly appearing linker errors, try completely deleting your build folder and rebuilding first. That can save you the headaches from trying to hunt down an error that actually simply shouldn't be there: There might be CMake cache variables floating around that have the wrong values, or something was renamed and not deleted, ...
I had the same issue as to OP but on on FreeBSD 13.1.
What solved the issue was simply adding:
int main()
{
}
Since the .cpp file was only an object file containing definitions and declarations using:
extern "C"
{
<all definitions and declarations code goes here>
}
Every time I tried compiling this, the compiler kept throwing the same error as to OP.
So all I did was add an empty main() function all the way at the bottom and code compiled with no errors.

Binding to custom .framework

I'm trying to bind to BugSense's lib but having a hard time trying to include the framework using -gcc_flags in the extra build arguments. BugSense provides a .framework and not a static .a lib. No amount of googling lead me to a solution to how to properly link the framework to my project.
So far I have something like this:
-v -v -v -gcc_flags "-framework ${ProjectDir}/../References/BugSense-iOS.framework"
I had copied the .framework folder to my References folder.
Building the project results in this mtouch error:
Error 1: mtouch failed with the following message:
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m: In function 'main':
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m:1838: warning: implicit declaration of function 'monotouch_enable_debug_tracking'
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m:1921: warning: implicit declaration of function 'mini_get_debug_options'
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m:1925: warning: implicit declaration of function 'mono_debugger_agent_parse_options'
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m:2059: warning: cast from pointer to integer of different size
/var/folders/XV/XVCgAKTfGEmAUQGlxdGm9E+++TU/-Tmp-/tmp36ed5372.tmp/main.m:2059: warning: initialization makes pointer from integer without a cast
ld: framework not found /Users/xxx/Projects/myProj/myProj/../References/BugSense-iOS.framework
collect2: ld returned 1 exit status
I believe its like libraries: you specify the name of the framework and then specify where to search.
-F <dir>
-framework <name>
So try this:
-gcc_flags "-F ${ProjectDir}/../References -framework BugSense-IOS"

Resources