gpt4 book ai didi

linux - 将库(来自汇编文件)与 Makefile 中的 main.c 链接

转载 作者:太空宇宙 更新时间:2023-11-04 09:15:37 25 4
gpt4 key购买 nike

我对汇编充满热情,想在家里用 linux 开始编码,而不是我通常使用的 mac。

我真的为这个问题纠结了 4 天。

您可以在以下网址找到我的 makefile 和克隆存储库:

<code>NAME =                libfts.a
ASM_FILES = ft_isascii \

OS := $(shell uname)
ifeq ($(OS), Darwin)
ASM_COMPILER = ~/.brew/bin/nasm -f macho64 -g
else
ASM_COMPILER = nasm -f elf64 -g
endif
ASM_SRC_DIR = srcs/
ASM_OBJ_DIR_NAME = obj
ASM_OBJ_DIR = $(ASM_OBJ_DIR_NAME)/
ASM_OBJ := $(addsuffix .o,$(ASM_FILES))
ASM_OBJ := $(addprefix $(ASM_OBJ_DIR),$(ASM_OBJ))
TEST = maintest.out
TEST_FILES = maintest
C_COMPILER = clang -Wall -Werror -Wextra -O3
TEST_DIR_NAME = test
TEST_DIR = $(TEST_DIR_NAME)/
TEST_OBJ := $(addsuffix .o,$(TEST_FILES))
TEST_OBJ := $(addprefix $(TEST_DIR),$(TEST_OBJ))
OBJ_PATHS := $(ASM_OBJ) $(TEST_OBJ)
all: $(NAME)
$(NAME): $(ASM_OBJ)
ar rc $(NAME) $(ASM_OBJ)
test: re $(TEST_OBJ)
$(C_COMPILER) -L. $(NAME) $(TEST_OBJ) -o $(TEST)
$(ASM_OBJ): $(ASM_OBJ_DIR)%.o: $(ASM_SRC_DIR)%.s
@/bin/mkdir -p $(ASM_OBJ_DIR)
$(ASM_COMPILER) $< -o $@
$(TEST_OBJ): $(TEST_DIR)%.o: $(TEST_DIR)%.c
$(C_COMPILER) -c -I. $< -o $@
clean:
-/bin/rm -f $(OBJ_PATHS)
/usr/bin/find . -name "$(ASM_OBJ_DIR_NAME)" -maxdepth 1 -type d -empty -delete
fclean: clean
-/bin/rm -f $(NAME)
-/bin/rm -f $(TEST)
re: fclean all
.PHONY: all clean fclean re

当我在 linux 上尝试“进行测试”时出现此错误消息:

    test/maintest.o: In function `main':
test/maintest.c:(.text+0x33): undefined reference to `ft_isascii'
undefined reference to etc.

.h内容:

#ifndef _LIBFTS
# define _LIBFTS

#include <stddef.h>

int ft_isascii(int c);

#endif

ft_isascii.s内容:

global _ft_isascii

section .text

_ft_isascii: ; int ft_isascii
and edi, 0xffffff80 ; mask with the 128 firsts bits left to 0 as ASCII range from 0 to 7f in hexa (just below 80)
sete al ; SETE sets AL to 1 if above condition code means "equal", otherwise it sets AL to 0.
movzx eax, al
ret

如果能提供解决此问题的任何提示,我将非常感激...

问候,

最佳答案

有两个问题需要解决:

首先,在 ELF 目标(除 macOS 之外的大多数 Unix)上,C 函数没有用下划线修饰。要修复您的代码,请从所有符号中删除前导下划线。确保在所有地方都将其删除。

其次,链接器在查看存档(.a 文件)时只选择它现在需要的文件来满足依赖性。因此,当您在 maintest.o 之前传递存档时,链接器根本不会从存档中获取任何内容,因为它不需要任何 ft_... 符号那一点。只有在链接器看到 maintest.o 后才需要这些符号。要解决此问题,请将 $(NAME) 操作数移至 $(TEST_OBJ) 之后。作为一般经验法则,始终在链接器命令行上将库放在目标文件之后。

在 macOS 上,你不会观察到这个问题,因为他们使用 lld,LLVM 链接器,这有点不寻常,因为它推迟了选择从文件中取出哪些对象,直到它查看了所有对象的符号表操作数,使您实际中断的调用工作。请不要依赖这种行为。

关于linux - 将库(来自汇编文件)与 Makefile 中的 main.c 链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48232993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com