linux - 是否已编译 X11 c 程序,出现未定义的引用错误,需要哪些库?
问题描述
我是 Linux 上的 c 编程新手。我的目标是创建一个高效的程序来监控已安装分区 (parm1) 上的可用空间,并在托盘中放置一个图标来表示它,显示我的名字 (parm2) 和可用空间百分比(计算 parm3 的脚本),每 xxx 秒运行一次该脚本 (parm4) 并在值更改时刷新图标 (图标文件名 parm5)。
对于初学者,我刚刚从这里复制了一个示例 c 程序,我只是想让它按原样编译和运行,以便在托盘中嵌入一个带有图标的程序。
C、Xlib 中的 freedesktop XEmbed 系统托盘客户端代码
我对其进行了调整以合并建议的更改并删除错误,它编译干净,但似乎需要添加库才能创建可执行文件。
我如何找出需要哪些库以及将它们放入的顺序?
/* from: https://stackoverflow.com/questions/45392284/freedesktop-xembed-systray-client-code-in-c-xlib */
#include <X11/Xutil.h>
#include <string.h>
#include <unistd.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
/* --------- XEMBED and systray stuff */
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
int usleep(useconds_t useconds); //pass in microseconds
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *, XErrorEvent *);
static int
error_handler(Display *display, XErrorEvent *error) {
trapped_error_code = error->error_code;
return 0;
}
void
trap_errors(void) {
trapped_error_code = 0;
old_error_handler = XSetErrorHandler(error_handler);
}
int
untrap_errors(void) {
XSetErrorHandler(old_error_handler);
return trapped_error_code;
}
void
send_systray_message(Display* dpy, long message, long data1, long data2, long data3) {
XEvent ev;
Atom selection_atom = XInternAtom (dpy,"_NET_SYSTEM_TRAY_S0",False);
Window tray = XGetSelectionOwner (dpy,selection_atom);
if ( tray != None)
XSelectInput (dpy,tray,StructureNotifyMask);
memset(&ev, 0, sizeof(ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = tray;
ev.xclient.message_type = XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = message;
ev.xclient.data.l[2] = data1; // <--- your window is only here
ev.xclient.data.l[3] = data2;
ev.xclient.data.l[4] = data3;
trap_errors();
XSendEvent(dpy, tray, False, NoEventMask, &ev);
XSync(dpy, False);
usleep(10000);
if (untrap_errors()) {
/* Handle errors */
}
}
/* ------------ Regular X stuff */
int
main(int argc, char **argv) {
int width, height;
XWindowAttributes wa;
XEvent ev;
Display *dpy;
int screen;
Window root, win;
/* init */
if (!(dpy=XOpenDisplay(NULL)))
return 1;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if(!XGetWindowAttributes(dpy, root, &wa))
return 1;
width = height = MIN(wa.width, wa.height);
/* create window */
win = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 0, 0, 0xFFFF9900);
/* call send_systray_messsage */
send_systray_message(dpy, SYSTEM_TRAY_REQUEST_DOCK, win, 0, 0); // pass win only once
XMapWindow(dpy, win);
XSync(dpy, False);
/* run */
while(1) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev); /* just waiting until we error because window closed */
}
}
}
$ gcc xmbed_system_tray.c -o xmbed_system_tray
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `trap_errors':
xmbed_system_tray.c:(.text+0x3a): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `untrap_errors':
xmbed_system_tray.c:(.text+0x57): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `send_systray_message':
xmbed_system_tray.c:(.text+0xa8): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xc2): undefined reference to `XGetSelectionOwner'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xe8): undefined reference to `XSelectInput'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x131): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1ab): undefined reference to `XSendEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1bf): undefined reference to `XSync'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `main':
xmbed_system_tray.c:(.text+0x1f3): undefined reference to `XOpenDisplay'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x24f): undefined reference to `XGetWindowAttributes'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2b2): undefined reference to `XCreateSimpleWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2ed): undefined reference to `XMapWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2fe): undefined reference to `XSync'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x316): undefined reference to `XNextEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x322): undefined reference to `XPending'
collect2: error: ld returned 1 exit status
解决方案
我没有找到任何显示任何内容的视频,但我确实找到了一个网站,在那里他显示了可能的图书馆或位置。因此,我猜测要么我的环境设置错误,所以它找不到它正在寻找的东西,或者它正在寻找的东西没有安装。
http://mech.math.msu.su/~nap/2/GWindow/xintro.html
这没有帮助,但我最终找到了另一个页面:
https://en.wikibooks.org/wiki/X_Window_Programming/Xlib
他们的示例程序有编译指令:
To Compile: gcc -O2 -Wall -o test test.c -L /usr/X11R6/lib -lX11 -lm
所以对于我的我尝试:
gcc -o xmbed_system_tray xmbed_system_tray.c -lX11
通过一次删除一个选项,我发现之前不存在的 -lX11 参数导致了失败,现在可执行文件被创建并运行。
该程序仅消耗约 1 mb 的内存,而我发现能够在托盘中运行程序的其他程序为 25 到 35 mb。
推荐阅读
- python - Pandas 从系列中获取月末值
- salesforce - SOQL 和 Apex - 将 SOQL 排除在 for 循环之外
- python - 如何在 Python 中从配置中导入标志时修复“ImportError: cannot import name 'flags'”
- c# - 从 C# 中的动态对象中删除属性及其值
- awk - 基于常见匹配模式过滤行(用户未知)
- pandas - 正确读取 json 文件
- android - 如何处理 Kotlin 中 EditText drawableRight 图标的点击监听器?
- angular - 构建角度库时无法读取未定义的属性“模块”
- excel - 我需要使用索引和匹配从另一列条件匹配的列中提取数据
- html - 有没有办法在我的网站上显示图片,前提是图片不是列表中的空值?