GCC编译出现链接命令失败错误:未定义符号问题排查
解决x86_64架构下未定义符号的链接错误
你遇到的这个链接错误本质很简单:你的编译命令只编译了max_pool.c这一个源文件,但load_image()和arrayUpScaling()的实际实现代码在其他.c文件里,链接器找不到这些函数的二进制实现,所以抛出了未定义符号的错误。
问题原因拆解
头文件(比如image_to_matrix.h、convolutional.h)只是给编译器提供函数的声明信息(告诉编译器“这个函数存在,它的参数和返回值是这样的”),但函数的实际代码逻辑是写在对应的.c源文件里的(比如image_to_matrix.c实现load_image,convolutional.c实现arrayUpScaling)。你当前的编译命令只处理了max_pool.c,链接器自然找不到其他函数的实现代码。
解决方案
1. 修改编译命令,包含所有依赖的源文件
把所有实现了用到的函数的.c文件都加到编译命令里,比如:
gcc -Wall -std=c11 -g -o max max_pool.c image_to_matrix.c convolutional.c
这条命令会:
- 分别编译
max_pool.c、image_to_matrix.c、convolutional.c为目标文件(.o) - 链接所有目标文件,生成最终的可执行文件
max
2. (可选)用Makefile简化编译流程
如果你的源文件比较多,每次手动输入所有文件名很麻烦,可以写一个简单的Makefile:
CC = gcc CFLAGS = -Wall -std=c11 -g TARGET = max # 把所有需要的.c文件都列在这里 SRCS = max_pool.c image_to_matrix.c convolutional.c $(TARGET): $(SRCS) $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) clean: rm -f $(TARGET)
之后只需要在终端运行make就能自动编译,运行make clean可以删除生成的可执行文件。
补充说明
哪怕所有文件都在同一目录,也必须把所有.c源文件都包含在编译命令里——头文件的存在只是让编译器通过语法检查,链接器需要的是函数的实际二进制代码,这些代码只能从对应的.c编译后的目标文件里获取。
你提供的相关代码与错误信息
主文件max_pool.c代码:
#include <stdio.h> #include <stdlib.h> #include "max_pool.h" #include "convolutional.h" #include "matrix_to_array.h" int main() { image im = load_image("doge.jpg"); int* result; int scale = 100; int* input = arrayUpScaling(im, im.h, im.w, im.c, scale); result = pool_max(im.h, im.w, im.c, input); int h = im.h; int w = im.w; int c = im.c; for (int k = 0; k < c; k++) { for (int i = 0; i < h; i++ ) { for (int j = 0; j < w; j++ ) { int dst_index = j + w*i + w*h*k; printf("result[%d][%d][%d]: %d ", i, j, k, result[dst_index]); } printf("\n"); } } return 0; }
convolutional.h代码:
#ifndef CON_H #define CON_H #include "image_to_matrix.h" int SIZE[3]; //This program is a multiplier which supports input to be 4/8/16 bits //It consists of three parts, a multiplier, an adder and an acumulator which //support 16/18/20/22 bits. This program will return a 8 bits value int* readImage(image im, int scale); int* get_Data_From_Con(int h, int w, int c, int* up_scaled_input, int filter_size, int filter[filter_size][filter_size], int stride, int scale); void buildSize(int* SIZE, int h, int w, int c); int** truncateArray(int h, int w, int filter_size, int** input, int col, int row); int** addPadding(int h, int w, int input[h][w], int h_padding, int w_padding); int** inputManagement(int h, int w, int filter_size, int input[h][w], int filter[filter_size][filter_size], int stride, int scale); int multiplier(int first, int second, int bitwidth, int scale); int accumulator(int previous, int product); int mat(int size, int** input, int filter[size][size], int scale); int* arrayUpScaling(image im, int h, int w, int c, int scale); float** arrayDownScaling(int h, int w, int scale, int** input); void freeIntArray(int rows, int** arr); void freeDoubleArray(int rows, float** arr); int relu(int input); #endif
max_pool.h代码:
#ifndef MAXP_H #define MAXP_H int* pool_max(int h, int w, int c, int* data); int selectMax(int h, int w, int filter_size, int input[h][w], int col, int row); #endif
image_to_matrix.h代码:
#ifndef IMA_H #define IMA_H typedef struct{ int w,h,c; float *data; } image; float get_pixel(image im, int x, int y, int c); image make_image(int w, int h, int c); image load_image(char *filename); image make_empty_image(int w, int h, int c); image load_image_stb(char *filename, int channels); void free_image(image im); #endif
错误信息:
Undefined symbols for architecture x86_64: "_arrayUpScaling", referenced from: _main in max_pool-7ba8aa.o "_load_image", referenced from: _main in max_pool-7ba8aa.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
内容的提问来源于stack exchange,提问作者Liu Hantao
相关产品推荐
相关产品推荐

