NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

xsrc/48928: Issue building static X11 clients



>Number:         48928
>Category:       xsrc
>Synopsis:       Issue building static X11 clients
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    xsrc-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 20 03:05:00 +0000 2014
>Originator:     Matthew Mondor
>Release:        NetBSD 6.1_STABLE
>Organization:
>Environment:
System: NetBSD ninja.xisop 6.1_STABLE NetBSD 6.1_STABLE (GENERIC_MM) #3: Mon 
Jul 1 19:08:46 EDT 2013 
root@ninja.xisop:/usr/obj/sys/arch/amd64/compile/GENERIC_MM amd64
Architecture: x86_64
Machine: amd64
>Description:

Attached is a minimal X11 test executable I borrowed to demonstrate the
issue.

To compile dynamically linked:

cc -o x11-test x11-test.c -I/usr/X11R7/include -L/usr/X11R7/lib 
-Wl,-rpath,/usr/X11R7/lib -lX11

x11-test:
        -lX11.7 => /usr/X11R7/lib/libX11.so.7
        -lxcb.1 => /usr/X11R7/lib/libxcb.so.1
        -lXau.7 => /usr/X11R7/lib/libXau.so.7
        -lgcc_s.1 => /usr/lib/libgcc_s.so.1
        -lc.12 => /usr/lib/libc.so.12
        -lXdmcp.7 => /usr/X11R7/lib/libXdmcp.so.7


To compile statically linked:

Attempt 1:
cc -o x11-test -static x11-test.c -I/usr/X11R7/include -L/usr/X11R7/lib 
-Wl,-rpath,/usr/X11R7/lib -lc -lX11 -lxcb -lXau -lXdmcp

/usr/X11R7/lib/libX11.a(lcInit.o): In function `_XlcInitLoader':
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:130: undefined 
reference to `_XlcGenericLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:134: undefined 
reference to `_XlcDefaultLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:138: undefined 
reference to `_XlcUtf8Loader'
/usr/X11R7/lib/libX11.a(lcInit.o): In function `_XlcDeInitLoader':
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:169: undefined 
reference to `_XlcGenericLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:173: undefined 
reference to `_XlcDefaultLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:177: undefined 
reference to `_XlcUtf8Loader'

After noticing that the libraries satisfying these symbols are located
at /usr/X11R7/lib/X11/locale/lib/common/ I realized that no statically
linkable versions existed either.  However, these seemed to be part of
the build, at /usr/obj/external/mit/xorg/lib/libX11/*/_pic.a so I
ensured their symbols were indexed with ranlib, and copied them
manually under names which can be statically linked.  Then the
following:

Attempt 2:

cc -o x11-test -static x11-test.c -I/usr/X11R7/include -L/usr/X11R7/lib 
-L/usr/X11R7/lib/X11/locale/lib/common/ -lxlibi18n -lximcp -lxlcDef 
-lxlcUTF8Load -lxlocale -lxomGeneric -lc -lX11 -lxcb -lXau -lXdmcp

/usr/X11R7/lib/libX11.a(lcInit.o): In function `_XlcInitLoader':
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:130: undefined 
reference to `_XlcGenericLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:134: undefined 
reference to `_XlcDefaultLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:138: undefined 
reference to `_XlcUtf8Loader'
/usr/X11R7/lib/libX11.a(lcInit.o): In function `_XlcDeInitLoader':
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:169: undefined 
reference to `_XlcGenericLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:173: undefined 
reference to `_XlcDefaultLoader'
/usr/xsrc/external/mit/libX11/dist/src/xlibi18n/lcInit.c:177: undefined 
reference to `_XlcUtf8Loader'

I might be missing something obvious, and would be glad to know what.

I've only investigated a bit, but it seems that the i18n support can
dlopen(3) dynamic vendor-specific code.  In my impression, that is
fine, as long as it can keep working with the default behavior when
those modules are unused or absent.  I'm not sure yet why the code
cannot be statically built despite this design.

This is only a minimal x11 test program, but the goal would be to be
able to distribute an application binary which is easy to distribute,
to use without installation and which does not break easily with OS
updates.  Ideally, I'd like to release it and not have to touch it,
potentially for years.

Using a standard package, it'd have to be released/updated regularily,
at pkgsrc and NetBSD releases, and a user would need root access to
upgrade it.  An alternative would be to provide all necessary library
dependencies in a custom tree, with a binary RPATH designed to load
them from the current location, which is probably what I'll end up
doing for now.  This however requires more work, and for the user it
means more movable/breakable parts.  There's also more user work
involved like extracting an archive, or more work involved for the
issuer like providing an installer.

>How-To-Repeat:

An attached minimal X11 test client is included below, and build
instructions are included in the above description.

>Fix:

Unknown


--MP_/io1OMq/_/BiTiAEp7u+UNey
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=x11-test.c

/* 
        Brian Hammond 2/9/96.    Feel free to do with this as you will!
*/

/* include the X library headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/* include some silly stuff */
#include <stdio.h>
#include <stdlib.h>

/* here are our X variables */
Display *dis;
int screen;
Window win;
GC gc;

/* here are our X routines declared! */
void init_x();
void close_x();
void redraw();

main () {
        XEvent event;           /* the XEvent declaration !!! */
        KeySym key;             /* a dealie-bob to handle KeyPress Events */    
        char text[255];         /* a char buffer for KeyPress Events */

        init_x();

        /* look for events forever... */
        while(1) {              
                /* get the next event and stuff it into our event variable.
                   Note:  only events we set the mask for are detected!
                */
                XNextEvent(dis, &event);
        
                if (event.type==Expose && event.xexpose.count==0) {
                /* the window was exposed redraw it! */
                        redraw();
                }
                if (event.type==KeyPress&&
                    XLookupString(&event.xkey,text,255,&key,0)==1) {
                /* use the XLookupString routine to convert the invent
                   KeyPress data into regular text.  Weird but necessary...
                */
                        if (text[0]=='q') {
                                close_x();
                        }
                        printf("You pressed the %c key!\n",text[0]);
                }
                if (event.type==ButtonPress) {
                /* tell where the mouse Button was Pressed */
                        int x=event.xbutton.x,
                            y=event.xbutton.y;

                        strcpy(text,"X is FUN!");
                        XSetForeground(dis,gc,rand()%event.xbutton.x%255);
                        XDrawString(dis,win,gc,x,y, text, strlen(text));
                }
        }
}

void init_x() {
/* get the colors black and white (see section for details) */        
        unsigned long black,white;

        dis=XOpenDisplay((char *)0);
        screen=DefaultScreen(dis);
        black=BlackPixel(dis,screen),
        white=WhitePixel(dis, screen);
        win=XCreateSimpleWindow(dis,DefaultRootWindow(dis),0,0, 
                300, 300, 5,black, white);
        XSetStandardProperties(dis,win,"Howdy","Hi",None,NULL,0,NULL);
        XSelectInput(dis, win, ExposureMask|ButtonPressMask|KeyPressMask);
        gc=XCreateGC(dis, win, 0,0);        
        XSetBackground(dis,gc,white);
        XSetForeground(dis,gc,black);
        XClearWindow(dis, win);
        XMapRaised(dis, win);
};

void close_x() {
        XFreeGC(dis, gc);
        XDestroyWindow(dis,win);
        XCloseDisplay(dis);     
        exit(1);                                
};

void redraw() {
        XClearWindow(dis, win);
};

--MP_/io1OMq/_/BiTiAEp7u+UNey--

>Unformatted:
 --MP_/io1OMq/_/BiTiAEp7u+UNey
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 


Home | Main Index | Thread Index | Old Index