Not declared Xvlib function during building

Hi. While building a certain software, I am confronted with this error message:

1
2
3
4
5
x11.cpp: In function ‘void SetupXvImage()’:
x11.cpp:1115:142: error: ‘XvShmCreateImage’ was not declared in this scope
   GUI.image->xvimage = XvShmCreateImage(GUI.display, GUI.xv_port, GUI.xv_format, NULL, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, &GUI.sm_info);
                                                                                                                                              ^
make: *** [x11.o] Error 1


I opened the file to inspect it and found a
1
2
#ifdef USE_XVIDEO
#include <X11/extensions/Xvlib.h> 

that I thought was missing from the x11.cpp. Then I considered that for some reason, the ifdef could be evaluating to false, and so I copied the #include statment above the ifdef. Yet, the error message persisted.


So, what else can be causing the error? I assume the pre-processor included the function in the x11.cpp file, as with everything else in the Xvlib.h
Open X11/extensions/Xvlib.h
Search for XvShmCreateImage

1. Does it even exist in that file?
2. If it does exist, does it have some #ifdef around it?

> and so I copied the #include statment above the ifdef.
Yeah, the better thing to do would have been to put -DUSE_XVIDEO on the compiler command line.

(Upstream) libXv of XOrg does not seem to have changed during last decade and that does declare
1
2
3
4
5
6
7
8
9
extern XvImage *XvShmCreateImage (
    Display *display,
    XvPortID port,
    int id,
    char *data,
    int width,
    int height,
    XShmSegmentInfo *shminfo
);

All the function declarations in the file are enclosed by _XFUNCPROTOBEGIN, _XFUNCPROTOEND macros.


If Xvlib.h in @colt's system is different, then where is it from?
1. Does it even exist in that file?
2. If it does exist, does it have some #ifdef around it?


1)Yes
2)It has #ifdef _XSHM_H_ and #endif (plus what keskiverto mentioned)

Yeah, the better thing to do would have been to put -DUSE_XVIDEO on the compiler command line.
Like passing it to CPPFLAGS?

If Xvlib.h in @colt's system is different, then where is it from?


On my system seems equal to the one you mentioned, even being much older.


Some other relevant info.

My original building command was:

CPPFLAGS="-I /xorg/X11-1.4.4/include/ -I /xorg/Xorgproto-2018.1/include/ -I /xorg/Xv-1.0.1/include/ -I /xorg/Xext-1.1.1/include/ -I /arquivos/Zlib-1.2.11/include/" LDFLAGS="-L/xorg/X11-1.4.4/lib/ -L/arquivos/Zlib-1.2.11/lib/" ./configure --prefix=/media/34GB/Arquivos-de-Programas-Linux/Snes9x-1.60-x11

After some thinking, I noticed that I was missing the path to Xvlib in LDFLAGS. Then I added it and tested again. To no avail. I decided then to do another test and added the path to the Xext lib, as I thought that the function could be in this library, due to the extern modifier. It didn't change anything.

Finally, I did check libXV and saw that the function is indeed in it:

00000000000033f0 T XvShmCreateImage
The message
error: ‘XvShmCreateImage’ was not declared in this scope

is from compiler and due to the translation unit -- the source code -- lacking suitable declaration.

The (lack of) symbols is a linker issue and it would then say that it cannot resolve.

If the lib has the symbol, why its headers seem to effectively lack it?

One could look for the string from sources:
grep -r XvShmCreateImage /xorg

and that presumably gives only one real hit, does it?


What is the _XSHM_H_? What does it enclose? Is it just a header guard?
The upstream: https://gitlab.freedesktop.org/xorg/lib/libxv/-/blob/master/include/X11/extensions/Xvlib.h?ref_type=heads
If I remove
#ifdef _XSHM_H_
and its
#endif
from the Xvlib.h that I am passing to configure, it finds the declaration of XvShmCreateImage. However it produces other errors:

1
2
3
4
5
6
7
8
9
In file included from x11.cpp:24:0:
/xorg/Xv-1.0.1/include/X11/extensions/Xvlib.h:378:4: error: ‘XShmSegmentInfo’ has not been declared
    XShmSegmentInfo *shminfo
    ^
x11.cpp: In function ‘void SetupXvImage()’:
x11.cpp:1115:142: error: cannot convert ‘XShmSegmentInfo*’ to ‘int*’ for argument ‘7’ to ‘XvImage* XvShmCreateImage(Display*, XvPortID, int, char*, int, int, int*)’
   GUI.image->xvimage = XvShmCreateImage(GUI.display, GUI.xv_port, GUI.xv_format, NULL, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, &GUI.sm_info);
                                                                                                                                              ^
make: *** [x11.o] Error 1
Last edited on
The macro _XSHM_H_ looks like an "include guard":
https://en.wikipedia.org/wiki/Include_guard

So, it should be defined by the header file called "xshm.h" to indicate that the header file has been included and to prevent multiple inclusions of that same file. If you define _XSHM_H_ yourself (or remove the check 😏) you are "pretending" that the header file has already been included, while in reality it probably hasn't. It will make any code fail that actually relies on the declarations from that header file!

So, I think, the correct solution would be including "xshm.h" at the proper location.
Last edited on
> The macro _XSHM_H_ looks like an "include guard"

No. (I was careless on my previous comment.)

The purpose of "include guard" is to prevent the system (preprocessor) from including same code multiple times into translation unit. Typical header looks like:
1
2
3
4
5
6
#ifndef MY_H
#define MY_H

// actual code

#endif 

The first pragma is ifndef -- if macro is not defined
The actual code is included, and #define MY_H evaluated only on first time.


The #ifdef _XSHM_H_ is not like that; something elsewhere defines (or does not) the _XSHM_H_, so someone else decides whether to have declarations, or not.

Does the pair
1
2
#ifdef _XSHM_H_
#endif 

contain all the declaration within the header, or just some subset? If subset, which declarations?


Like before, I would check where the macro is mentioned (other than this header):
grep -r _XSHM_H_ /xorg
double-post
Last edited on
The purpose of "include guard" is to prevent the system (preprocessor) from including same code multiple times into translation unit.

Yes, that's the primary purpose.

Anyways, the same macro is often used to check if a specific header file has been included, so that functions or types from that header can be used conditionally in other source code files:

1
2
3
4
5
6
7
8
void my_function()
{
#ifdef _FOOBAR_H_
    SomeFunctionFromFoobarH(); /* <-- available only if "foobar.h" was included before */
#else
    /* fallback implemenatation here */
#endif
}
Last edited on
True. I have lived a simple life, not asking "Do we have X? If yes, then we can have Y too." -- not using guard macros outside the header they guard.


including "xshm.h" at the proper location.

The "proper" means thus before XVlib.h is included.
Topic archived. No new replies allowed.