Loading gstreamer plugins in static executable - static-libraries

I need to build a static Linux executable with gstreamer and use the queue factory which is part of the coreelements plugin. What I did was:
Configured gstreamer (version 1.12.4) with: ./configure --enable-static --disable-shared --enable-static-plugins
Built it and gst-plugin-base
Added in my code:
GST_PLUGIN_STATIC_DECLARE(coreelements);
GST_PLUGIN_STATIC_REGISTER(coreelements);
Linked my app with libgstcoreelements.a (together with gstreamer-1.0, gstbase-1.0 and gstapp-1.0)
Linking fails with:
undefined reference to gst_plugin_coreelements_register()
I can verify that gst_plugin_coreelements_register is in the static library file:
$ nm libgstcoreelements.a |grep gst_plugin_coreelements_register
00000000000002c0 T gst_plugin_coreelements_register
Do you see what I am doing wrong?

What I was missing is an extern "C" { } block around the first gstreamer macro as it declares an extern C-style function, and my application is compiled with g++:
extern "C" {
GST_PLUGIN_STATIC_DECLARE(coreelements);
}

Related

Cgo "undefined reference" (gstreamer)

I am writing something using cgo to interact with the gstreamer-1.0 library. I have everything almost working perfectly, but for some reason an entire header file's objects are not getting imported correctly.
go version go1.15.2 linux/amd64 for whatever that is worth
package main
// #cgo pkg-config: gstreamer-1.0
// #cgo CFLAGS: -Wno-deprecated-declarations
// #include <gst/gst.h> // using this file extensively with no issues
// #include <gst/app/gstappsink.h> // objects in this file are not getting read, but the compiler is having no issue reading it
import "C"
func init () { C.gst_init(nil, nil) }
func main () {
// ...
C.gst_app_sink_pull_sample() // a non-variadic function that does take args
// but cgo doesn't even think it exists.
// ...
}
The error back from the compiler: /tmp/go-build/cgo-gcc-prolog:64: undefined reference to 'gst_app_sink_pull_sample'
I've looked at the header file and gst_app_sink_pull_sample is indeed there. I can reproduce this both trying to build locally and in the golang docker container.
If I remove the include entirely the error is different: could not determine kind of name for C.gst_app_sink_pull_sample.
So am I the problem or is gstreamer the problem?
The appsrc and appsink symbols are not part of the base gstreamer library. Instead they are found in the extra library gstreamer-app-1.0. Add this library to your cgo pkgconfig line and it should find the missing symbols.
"undefined reference to xxx" means the C compiler of cgo recognize the definitions but it can't find the implementations (covered by corresponding C libraries)
This indicates that you have your C header files imported correctly. To solve the undefined reference problem, you just have to add some thing as below if your dynamic library is called libgstreamer.so.1.0.0
# cgo LDFLAGS: -lgstreamer

undefined C type 'int' with gcc 9.1.0 on solaric

I built gcc 9.1.0 on Solaris 11 (SPARC) from sources (GNU). The build went well and CGO free Go code can be compiled and works.
With CGO code the gccgo build does not compile.
go code referencing any C standard type like C.int returns an error:
sh> go build ./...
./main.go:18:2: call of non-function C.f
./main.go:18:6: invalid conversion to C.int: undefined C type 'int'
Here is the simple example code which does not build.
package main
/*
#include <stdio.h>
void f(int i) {
fprintf(stdout,"INT: %d\n",i);
}
*/
import "C"
import (
"fmt"
)
func main() {
// Simple C function call.
C.f(C.int(1))
fmt.Println("ABC")
}
On other platforms the C type is referenced correctly. Does I have missed an compiler flag during gcc compile?
configure of gcc is called using:
../configure --prefix=<path>/gcc-solaris-9.1.0 --enable-languages=c,c++,go,objc,lto
Does anyone has a hint how to build gccgo on Solaris SPARC correctly?
Is there an header include file dependency missing, which is on Solaris needed?

Coudn't run code used std::async on GCC 5.3.0

I was practicing std::asyn function that introduced in c++11, I wrote a simple example
#include<future>
#include<iostream>
using namespace std;
void check()
{
cout<<"some"<<endl;
}
int main()
{
auto p=std::async(std::launch::async,check);
p.get();
}
Yes very simple to start off with and i am compiling it using GCC 5.3.0
g++ -std=c++11 practise.cpp -lpthread
and the error
practise.cpp: In function 'int main()':
practise.cpp:13:47: error: invalid use of incomplete type 'class std::future<int>'
auto p=std::async(std::launch::async,chech);
^
In file included from practise.cpp:1:0:
C:/Program Files/mingw32/i686-w64-mingw32/include/c++/future:115:11: note: declaration of 'class std::future<int>'
class future;
^
Am i missing anything? is the way i linked lpthread is ok? i am on windows 7.
Your problem looks very similar to the one from this SO:
c++11 std::async doesn't work in mingw
You should check what gcc -v returns for 'Thread model:'. In above SO it returns win32 - and quite possibly mingw still does not support async/future in this mode.
In my mingw installation - also 5.3.0, I have Thread model: posix. I checked the exact same compile flags as yours and your example always compiles fine.
So my suggestion is for you to first check thread model with gcc -v, if its non posix, then reinstall mingw with posix threads. You choose threads model when running mingw-w64-install.exe installer/

toquelib behaves different with static and dynamic linking

This is puzzling me...
I have a code that looks like this:
#include <stdio.h>
#include <pbs_ifl.h>
int doSomeStuff()
{
char *server_name;
int c;
server_name = pbs_default();
c = pbs_connect(server_name);
printf("pbs_errno %d\n",pbs_errno);
// do some stuff
pbs_disconnect(c);
}
When I compile it with:
gcc -static -o executablename sourcefile.c -ltorque
It works allright, compiling with '-static'. pbs_errno is 0 and I can do my stuff.
But if I remove the '-static' flag it starts giving me this message when I run it:
munge: Error: Unable to access "/var/run/munge/munge.socket.2": No such file or directory
So... I start the munge service (munged) and it stops complaining about it, but instead I get pbs_errno=15033 and can't get anything from the cluster (do my stuff).
Any ideas?
I don't know if I delete de question or answer it, but it seems so be solved... so I'm posting the solution here.
I had 2 versions of the lib installed, one via yum other via source.
Since only the compiled code had the static libs, when I was linking -static gcc was linking with the compiled code and when I was linking dynamic it was linking with the yum version.
I just had to enforce the linking with the right libs adding the following flag when liking:
-Wl,-rpath=/usr/local/lib

Link libquadmath with c++ on linux

I have an example code:
#include <quadmath.h>
int main()
{
__float128 foo=123;
cosq(foo);
return 0;
}
I tried to compile it with the following commands:
g++ f128.cpp -lquadmath
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a /usr/lib64/libquadmath.so.0
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a /usr/lib64/libquadmath.so.0 /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a
All these commands produce one and the same error:
f128.cpp:(.text+0x1b): undefined reference to `cosq(__float128)'
I also tried to declare cosq as follows, without inluding quadmath.h. Declarations of such style are used in C++ interface to fortran subroutines in other programs, and they work well.
extern "C" __float128 cosq_(__float128 *op);
extern "C" __float128 cosq_(__float128 op);
extern "C" __float128 cosq(__float128 *op);
...and so on...
Result was the same.
Then I tried to use cosq in Fortran:
PROGRAM test
REAL*16 foo
REAL*16 res
foo=1;
res=cos(foo)
PRINT *,res
END
This program compiles and executes well (prints the answer with lots of digits), so cosq works in it. This program was compiled with no options: gfortran f128.f90.
OS is OpenSUSE 12.1, gcc version is 4.6.2. *.h, *.a and *.so files mentioned are provided by gcc46-fortran and libquadmath46 packages.
What is the proper way to use cosq and other quadmath functions in C++? I wouldn't like to write Fortran wrappers for them.
First, according to Nikos C. advise, I boot up OpenSUSE 12.2 liveCD (which has gcc 4.7.1) on another machine, but got the same error.
Then I posted this question to OpenSUSE forums.
Martin_helm's answer shows that the problem is distro-independent and the solution is trivial:
extern "C" {
#include <quadmath.h>
}
This works fine on all my machines. Program can be compiled with g++ prog.cpp -lquadmath.

Resources