You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行make命令生成.so文件时遇‘undefined reference’错误求助

问题排查与解决方案

核心错误原因

你的链接错误源于Makefile中共享库的生成逻辑、参数配置存在多处问题,导致单个独立的.so文件无法找到跨文件的函数实现。以下是具体问题点和修正方案:


具体问题分析

  1. 头文件路径配置错误
    CFLAGS中的-I /usr/lib完全无效,应该指向subfolder/includes目录,否则编译时无法识别自定义头文件,可能引发函数声明缺失或不匹配。

  2. 共享库生成方式错误
    当前规则将每个.c文件单独编译为.so,导致每个共享库仅包含单个源文件的代码。当某个.so中的函数调用另一个.so的函数时,由于未在生成共享库时处理依赖,必然出现未定义引用。

  3. LIBS参数配置错误

    • -L后未指定库搜索路径,直接跟-lpq会让链接器误将-lpq当作路径处理,无法找到PostgreSQL库;
    • -Wl,-rpath后缺少具体的运行时库搜索路径,程序运行时可能找不到共享库。
  4. 可执行文件链接逻辑错误
    直接将所有独立.so文件作为输入链接成可执行文件,不符合共享库的标准使用方式,应该链接整合后的共享库而非零散文件。


修正后的Makefile

APP := Test_app
APP_INSTALL_DIR ?= /home

# 区分主程序和子模块源文件
MAIN_SRC := main.c
SUB_SRCS := $(wildcard subfolder/srcs/*.c)

# 头文件路径 + 共享库必需的位置无关代码编译选项
CFLAGS := -I subfolder/includes -fPIC
# 按需添加系统头文件路径(比如PostgreSQL的头文件路径)
# CFLAGS += -I /usr/include/postgresql

# 修正库参数:指定库搜索路径、运行时路径,链接必要系统库
LIBS := -L. -lpq -ldl -Wl,-rpath=.

# 子模块目标文件与共享库
SUB_OBJS := $(SUB_SRCS:.c=.o)
SUB_SO := libsub.so

all: $(APP)

# 编译子模块目标文件
%.o: %.c $(wildcard subfolder/includes/*.h) Makefile
	$(CC) -c -o $@ $(CFLAGS) $<

# 将子模块所有目标文件打包为一个共享库
$(SUB_SO): $(SUB_OBJS) Makefile
	$(CC) -shared -o $@ $^ $(LIBS)

# 编译主程序并链接共享库
$(APP): $(MAIN_SRC) $(SUB_SO) Makefile
	$(CC) -o $@ $(MAIN_SRC) $(CFLAGS) -lsub $(LIBS)

install: $(APP)
	cp -rv $(APP) $(SUB_SO) $(APP_INSTALL_DIR)

clean:
	rm -rf $(SUB_OBJS) $(APP) $(SUB_SO)

关键修正说明

  • 添加-fPIC:生成共享库必须使用位置无关代码,这是链接器的强制要求;
  • 合并子模块为单个共享库:将subfolder下的所有源文件编译为目标文件后打包成libsub.so,确保所有函数实现都在同一个库中,解决跨文件引用问题;
  • 修正头文件与库路径:明确指定自定义头文件路径和库搜索路径,避免链接器找不到依赖;
  • 标准化可执行文件链接:直接编译main.c并通过-lsub链接生成的共享库,符合Linux共享库的使用规范。

如果function_name来自第三方系统库而非自定义代码,请确保对应的库已添加到LIBS中(例如添加-lxxx)。

内容的提问来源于stack exchange,提问作者Basavaraj Kittali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:33:11