【问题标题】:GCC Linking with .o fileGCC 与 .o 文件的链接
【发布时间】:2017-12-14 19:46:50
【问题描述】:

我正在尝试编译我的代码,但它不起作用。我在学校编译了这个,但我不能在我的家用电脑上编译它。我似乎无法弄清楚为什么。我需要修复这个错误才能继续我的任务。另外,这个 list.o 文件是 profs 文件。我必须使用这个文件。

我尝试过的解决方案有哪些? 我已将 gcc 更新为 gcc-7。 我找到了 libc.a

/usr/lib/x86_64-linux-gnu/libc.a
/usr/share/doc/libklibc/README.klibc.arch

编辑:我尝试在没有 -fPIC 的情况下进行编译

gcc -m64 -pthread -Wall -std=c99 -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol...

这是来自终端:

gcc -m64 -pthread -Wall -std=c99 -fPIC  -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol `headlist' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

这是我的制作文件:

CC = gcc
CFLAGS = -m64 -pthread -Wall -std=c99 -fPIC 
PROG = run
OBJS = main.o as2.o list.o

run: $(OBJS)
    $(CC) $(CFLAGS) -o $(PROG) $(OBJS)

main.o: main.c list.h as2.h
     $(CC) $(CFLAGS) -c main.c

as2.o: as2.c as2.h list.h
    $(CC) $(CFLAGS) -c as2.c

clean:
    rm main.o as2.o run

这是我的包括:

#include <netinet/in.h> 
#include <sys/socket.h> 
#include <netdb.h>  
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <pthread.h> 
#include "list.h"
#include "as2.h"

有什么想法/解决方案吗?

【问题讨论】:

  • 我的猜测是list.o 是在没有-fPIC 的情况下编译的,并且将带有和不带有此标志的对象混合不是一个好主意。尝试重新编译没有那个标志。
  • @rodrigo 感谢您的回复!我忘了提到我之前也尝试过不使用 -fPIC 进行编译。它仍然行不通。 gcc -m64 -pthread -Wall -std=c99 -o run main.o as2.o list.o /usr/bin/ld: list.o: 针对未定义符号重定位 R_X86_64_32S
  • 嗯,您在编辑中添加的行没有编译任何内容,它正在链接。您可以尝试在没有-fPIC 的情况下编译和链接所有文件,以防万一...
  • 我仍然遇到同样的错误。我想我应该更清楚这个问题。当我尝试将 .o 文件与我的 profs list.o 链接时,它给了我描述中看到的这个错误。我曾尝试在不同的地方操作 -fPIC,但它仍然给我同样的错误。很抱歉造成混乱。
  • 告诉我们什么是你可以在学校编译的 OS + 版本,以及你不能在家里编译它的 OS + 版本。还有 GCC 版本。

标签: c gcc compiler-errors linker object-files


【解决方案1】:

编辑: 将拼写从 LFLAGS 更改为 LDFLAGS 以安抚一些评论。

编辑: 移动了 -c 选项以安抚一些评论。

注意:all 通常是 make 文件中的第一个目标。

注意:使用:= 而不是=,因此宏只会被评估一次。

注意:list.o 已在当前目录中可用(根据 OPs 问题),因此未在 makefile 中编译。但仅与其他目标文件链接以生成可执行文件

您的 makefile 似乎有一些疏忽。建议:

CC := gcc
RM := rm -f

CFLAGS := -ggdb -m64 -pthread -Wall -Wextra -pedantic -std=c99
#LDFLAGS :=   <-- use the default value

PROG := run
OBJS := main.o as2.o list.o
HDRS := list.h as2.h



.PSEUDO: all clean

all: $(PROG)

$(PROG): $(OBJS)
    $(CC)  -ggdb -o $(PROG) $(OBJS) $(LDFLAGS)

main.o: main.c $(HDRS)
     $(CC) $(CFLAGS) -c main.c -o main.o -I.

as2.o: as2.c $(HDRS)
    $(CC) $(CFLAGS) -c as2.c -o as2.o -I.

clean:
    $(RM) main.o as2.o run

【讨论】:

  • 不要将-c 放在CFLAGS 中,它会限制可以使用的位置。另外,您不想向初学者解释您进行了哪些更改以及为什么进行了更改?
  • IMO:一定要把 -c 标志放在 CFLAGS 中,为什么,因为编译是唯一应该提及 CFLAGS 的时间。对于链接,有 LFLAGS(应该放在链接命令行的末尾附近)
  • 嘿 user362949,什么是 -ggdb、-m64、-Wextra、-pendantic、-I。 ?这些对我有什么帮助?
  • 你的make文件没有分隔符? @user362949
  • 我假设您的意思是 LDFLAGS 而不是 LFLAGS,并且 GNU Make 的 implicit rules-c 添加到规则中,而不是 CFLAGS,并且还在 @987654337 中使用 CFLAGS @ 规则(一步编译 链接,因此同时使用 CFLAGSLDFLAGS)。所以你的选择是非常规的,不符合常见的用法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
相关资源
最近更新 更多