[Xcb] [patch] XCB headers are unusable.

Josh Triplett josh at freedesktop.org
Fri Aug 18 20:44:33 PDT 2006


Zephaniah E. Hull wrote:
> While attempting to get XCB working for a new extension, I came across a
> tiny problem.
> 
> XCB's headers all include "xcb.h", and in some cases go further to
> include other xcb header files in the same fashion.
> 
> The .pc files all say to add -I/usr/include, not /usr/include/X11/XCB,
> so without further dancing it is impossible to include any of them.

This should actually work fine; you can include the headers quite easily
either from within XCB or from an arbitrary program.  User programs must
include the headers by saying #include <X11/XCB/xcb.h>, just as users of
Xlib say #include <X11/Xlib.h>.  Because the XCB headers themselves
include other XCB headers by saying #include "xcb.h", using doublequotes
rather than angle brackets, the compiler will find the other headers
alongside the one doing the including.  Some examples:

josh at josh-mobile:/tmp$ ls /usr/include/X11/XCB
bigreq.h     glx.h     screensaver.h  xcb.h      xf86dri.h   xtest.h
composite.h  randr.h   shape.h        xcb.xsd    xfixes.h    xv.h
damage.h     record.h  shm.h          xcbext.h   xprint.h    xvmc.h
dpms.h       render.h  sync.h         xcbxlib.h  xproto.h
extensions   res.h     xc_misc.h      xevie.h    xproto.xml
josh at josh-mobile:/tmp$ cat xcbtest.c
#include <X11/XCB/xcb.h>
#include <X11/XCB/render.h>
#include <X11/XCB/randr.h>
#include <X11/XCB/shape.h>
#include <X11/XCB/xfixes.h>
#include <X11/XCB/xv.h>

int main(int argc, char *argv[])
{
    return 0;
}
josh at josh-mobile:/tmp$ grep include /usr/include/X11/XCB/xfixes.h
#include "xcb.h"
#include "render.h"
#include "shape.h"
josh at josh-mobile:/tmp$ gcc xcbtest.c -o xcbtest
josh at josh-mobile:/tmp$

Note the lack of any -I options.

A simple example:

josh at josh-mobile:/tmp/temp$ tree
.
|-- dir
|   |-- a.h
|   `-- b.h
`-- src
    `-- main.c

2 directories, 3 files
josh at josh-mobile:/tmp/temp$ cat dir/a.h
#include "b.h"
josh at josh-mobile:/tmp/temp$ cat dir/b.h
/* Empty */
josh at josh-mobile:/tmp/temp$ cat src/main.c
#include <dir/a.h>

int main(int argc, char *argv[])
{
    return 0;
}
josh at josh-mobile:/tmp/temp$ cd src/
josh at josh-mobile:/tmp/temp/src$ gcc -I.. main.c
josh at josh-mobile:/tmp/temp/src$

Note that the -I option only points to .. AKA /tmp/temp, *not*
/tmp/temp/dir, and that main.c must refer to the includes with the dir/
prefix; however, dir/a.h can refer to dir/b.h as "b.h" with no dir/ prefix.

Furthermore, the directory containing a.h, dir/, gets searched before
the directory containing main.c, and before any directory specified with
a -I option, which should avoid any conflict with other headers used in
the X server:

josh at josh-mobile:/tmp/temp/src$ mkdir ../wrongdir
josh at josh-mobile:/tmp/temp/src$ echo '#error Wrong header!' > b.h
josh at josh-mobile:/tmp/temp/src$ echo '#error Wrong header!' >
../wrongdir/b.h
josh at josh-mobile:/tmp/temp/src$ gcc -I.. -I../wrongdir main.c
josh at josh-mobile:/tmp/temp/src$ gcc -I../wrongdir -I.. -I../wrongdir main.c
josh at josh-mobile:/tmp/temp/src$ gcc -I../wrongdir -I.. main.c
josh at josh-mobile:/tmp/temp/src$

Also note that if you use angle brackets to reference b.h, the search no
longer finds dir/b.h, and thus fails:

josh at josh-mobile:/tmp/temp/src$ echo '#include <b.h>' > ../dir/a.h
josh at josh-mobile:/tmp/temp/src$ gcc -I.. main.c
In file included from main.c:1:
../dir/a.h:1:15: error: b.h: No such file or directory
josh at josh-mobile:/tmp/temp/src$ gcc -I../wrongdir -I.. main.c
In file included from ../dir/a.h:1,
                 from main.c:1:
../wrongdir/b.h:1:2: error: #error Wrong header!
josh at josh-mobile:/tmp/temp/src$ gcc -I.. -I../wrongdir main.c
In file included from ../dir/a.h:1,
                 from main.c:1:
../wrongdir/b.h:1:2: error: #error Wrong header!

(Note that in no case did it find b.h in the same directory as main.c .)


If this explanation does not resolve the problem, please provide some
additional information on an erroneous scenario that your patch would avoid.

> Adding /usr/include/X11/XCB to the include path would solve the problem,
> but not even vaguely nicely as it would pollute the header namespace
> quite awfully.

Most definitely; we chose the header names on the assumption that they
would get referenced with the X11/XCB/ prefix.


A few more comments about your patch below.

> --- a/xcb/src/Makefile.am
> +++ b/xcb/src/Makefile.am
[...]
> @@ -20,27 +23,27 @@ lib_LTLIBRARIES = libXCB.la \
>                    libXCBxvmc.la
>  
>  EXTHEADERS = \
> -		extensions/bigreq.h \
> -		extensions/composite.h \
> -		extensions/damage.h \
> -		extensions/dpms.h \
> -		extensions/glx.h \
> -		extensions/randr.h \
> -		extensions/record.h \
> -		extensions/render.h \
> -		extensions/res.h \
> -		extensions/screensaver.h \
> -		extensions/shape.h \
> -		extensions/shm.h \
> -		extensions/sync.h \
> -		extensions/xc_misc.h \
> -		extensions/xevie.h \
> -		extensions/xf86dri.h \
> -		extensions/xfixes.h \
> -		extensions/xprint.h \
> -		extensions/xtest.h \
> -		extensions/xv.h \
> -		extensions/xvmc.h
> +		$(XCB_HDIR)/bigreq.h \
> +		$(XCB_HDIR)/composite.h \
> +		$(XCB_HDIR)/damage.h \
> +		$(XCB_HDIR)/dpms.h \
> +		$(XCB_HDIR)/glx.h \
> +		$(XCB_HDIR)/randr.h \
> +		$(XCB_HDIR)/record.h \
> +		$(XCB_HDIR)/render.h \
> +		$(XCB_HDIR)/res.h \
> +		$(XCB_HDIR)/screensaver.h \
> +		$(XCB_HDIR)/shape.h \
> +		$(XCB_HDIR)/shm.h \
> +		$(XCB_HDIR)/sync.h \
> +		$(XCB_HDIR)/xc_misc.h \
> +		$(XCB_HDIR)/xevie.h \
> +		$(XCB_HDIR)/xf86dri.h \
> +		$(XCB_HDIR)/xfixes.h \
> +		$(XCB_HDIR)/xprint.h \
> +		$(XCB_HDIR)/xtest.h \
> +		$(XCB_HDIR)/xv.h \
> +		$(XCB_HDIR)/xvmc.h

Looks like your patch moves the generated extension headers out of the
extensions directory in the source, which seems fine; we've thought
about doing that for a while.

> @@ -66,16 +69,16 @@ EXTSOURCES = \
>  EXTENSIONS = $(EXTSOURCES) $(EXTHEADERS)
>  
>  ESSENTIAL_EXTENSIONS = \
> -		extensions/bigreq.h \
> +		$(XCB_HDIR)/bigreq.h \
>  		extensions/bigreq.c \
> -		extensions/xc_misc.h \
> +		$(XCB_HDIR)/xc_misc.h \
>  		extensions/xc_misc.c

If we move the generated headers out of extensions/, we might as well
move the generated sources out of there too, and stop using the directory.

> @@ -189,6 +192,14 @@ vpath %.xml $(XCBPROTO_XCBINCLUDEDIR) $(
>  	                          $(XCBPROTO_XCBINCLUDEDIR)/extensions/ \
>  	            -o $@ $(srcdir)/c-client.xsl $< 
>  
> +$(XCB_HDIR)/%.h: %.xml c-client.xsl
> +	@n=`dirname $*`; test -d $$n || (echo mkdir $$n; mkdir $$n)
> +	$(XSLTPROC) --stringparam mode header \
> +	            --stringparam base-path $(XCBPROTO_XCBINCLUDEDIR)/ \
> +	            --stringparam extension-path \
> +	                          $(XCBPROTO_XCBINCLUDEDIR)/extensions/ \
> +	            -o $@ $(srcdir)/c-client.xsl $< 
> +

Why did you add this rule to generate headers in the $(XCB_HDIR)
directory, but not remove the previous rule to generate headers in the
extensions/ directory?

- Josh Triplett

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: OpenPGP digital signature
Url : http://lists.freedesktop.org/archives/xcb/attachments/20060818/b8d33992/signature.pgp


More information about the Xcb mailing list