编译依赖glib-2.0的C/C++程序时出现未定义引用错误如何解决?
解决DBus-GLib函数未定义引用的问题
你的错误是典型的链接阶段缺少依赖库导致的,再加上Makefile的编译规则有几个关键错误,咱们一步步理清楚:
核心问题分析
undefined reference错误说明编译器能找到函数的声明(因为你包含了正确的头文件),但链接器找不到这些函数的实现代码——这些函数属于dbus-glib-1库,你的Makefile没有在链接阶段正确引入这个库,同时编译规则也有问题。
具体问题点
- 编译目标文件时缺少
-c选项
你生成main.o的命令没有加-c,编译器会直接生成可执行文件而不是目标文件,这会导致后续链接阶段出错。-c的作用是告诉编译器只编译源代码,生成目标文件(.o),不进行链接。 - 库链接参数放错了阶段
pkg-config --libs ...输出的是链接时需要的库路径和库名,应该放在生成最终可执行文件的链接阶段,而不是编译阶段。编译阶段只需要--cflags来获取头文件路径。 - 缺少dbus相关库的链接
你只引入了glib-2.0的库,但g_dbus_setup_bus、g_dbus_client_new这些函数属于dbus-glib-1库,同时还依赖dbus-1,所以需要把这两个库也加入pkg-config的参数里。 - 代码里的未使用变量警告
你声明了GDBusClient *client但没使用,可以添加一行(void)client;来消除警告,或者如果不需要就删掉这个变量。
修正后的Makefile
# 如果你是纯C代码,用gcc更合适,g++是C++编译器 CC=gcc # 用pkg-config获取编译参数,不用手动写头文件路径,更可靠 CFLAGS=-I. -Wall -std=c11 `pkg-config --cflags glib-2.0 dbus-1 dbus-glib-1` # 链接参数单独提取 LDFLAGS=`pkg-config --libs glib-2.0 dbus-1 dbus-glib-1` OBJ = main.o default: program # 编译目标文件,加-c选项 main.o: main.c hello.h $(CC) $(CFLAGS) -c main.c -o main.o # 链接阶段加入LDFLAGS program: $(OBJ) $(CC) $(OBJ) $(LDFLAGS) -o program clean: -rm -f main.o -rm -f program
修正后的代码(消除警告+资源释放)
#include <cstddef> #include <cstdio> #include <iostream> #include <glib.h> #include <dbus/dbus.h> #include <gdbus/gdbus.h> static DBusConnection *dbus_conn; int main(int argc, char * argv[]){ GDBusClient *client; dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL); if (!dbus_conn) { g_printerr("Failed to connect to system bus\n"); return 1; } client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez"); // 消除未使用变量警告 (void)client; // 记得释放资源,避免内存泄漏 if (client) g_object_unref(client); dbus_connection_unref(dbus_conn); return 0; }
验证步骤
- 替换你的Makefile和代码
- 执行
make clean清理旧文件 - 执行
make编译,应该不会再出现未定义引用的错误了
内容的提问来源于stack exchange,提问作者Kyle




