简体   繁体   English

将库(来自程序集文件)与Makefile中的main.c链接

[英]Linking library (from assembly files) with main.c in Makefile

Im passionate about assembly and wanted to start coding from home on linux instead of mac I usually use. 我对汇编充满热情,并希望从Linux而非我通常使用的Mac开始在家编写代码。

I really struggle for 4 days about this issue. 我真的为这个问题奋斗了4天。

you can find my makefile and clone repository at the following url: 您可以在以下网址找到我的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

I have this error message when I try "make test" on the linux: 当我在linux上尝试“进行测试”时,出现以下错误消息:

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

.h content: .h内容:

#ifndef _LIBFTS
# define _LIBFTS

#include <stddef.h>

int         ft_isascii(int c);

#endif

ft_isascii.s content: 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

I would REALLY be thanksful for any tips to solve this issue... 对于解决此问题的任何提示,我将非常感谢...

Regards, 问候,

There are two problems to be fixed: 有两个问题需要解决:

First, on ELF targets (most Unixes except macOS), C functions are not decorated with an underscore. 首先,在ELF目标(除macOS以外的大多数Unix)上,C函数没有下划线修饰。 To fix your code, remove the leading underscore from all symbols. 要修复您的代码,请从所有符号中删除下划线。 Make sure to remove it everywhere. 确保将其删除。

Second, the linker when looking at an archive ( .a file) only picks files it needs right now to satisfy dependencies. 其次,链接器在查看档案( .a文件)时仅选择它现在需要满足依赖性的文件。 So when you pass the archive before maintest.o , the linker doesn't take anything from the archive at all as it doesn't need any ft_... symbols at that point. 因此,当您在maintest.o之前传递存档时,链接器根本不会从存档中获取任何内容,因为此时它不需要任何ft_...符号。 These symbols are only needed once the linker has seen maintest.o . 仅当链接程序看到maintest.o时才需要这些符号。 To fix this issue, move the $(NAME) operand to after $(TEST_OBJ) . 要解决此问题,请将$(NAME)操作数移动到$(TEST_OBJ) As a general rule of thumb, always place libraries after object files on the linker command line. 一般而言,始终将库放在链接器命令行上的目标文件之后。

On macOS, you won't observe this problem because they use lld, the LLVM linker, which is a bit unconventional in that it defers the choice which objects to take out of archives until it has looked at the symbol tables of all operands, making your actually broken invocation work. 在macOS上,您将不会观察到此问题,因为它们使用LLVM链接器lld,这有点不合常规,因为它在查看所有操作数的符号表之前会推迟选择要从存档中删除的对象的选择,您实际上已中断的调用工作。 Don't depend on this behaviour, please. 请不要依赖这种行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM