Home Linking library (from assembly files) with main.c in Makefile
Reply: 1

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

Tonyoh Published in 2018-01-12 19:39:03Z

Im passionate about assembly and wanted to start coding from home on linux instead of mac I usually use.

I really struggle for 4 days about this issue.

you can find my makefile and clone repository at the following url:

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

OS := $(shell uname)
ifeq ($(OS), Darwin)
ASM_COMPILER =      ~/.brew/bin/nasm -f macho64 -g
ASM_COMPILER =      nasm -f elf64 -g
ASM_SRC_DIR =       srcs/
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)
    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 $@
    -/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:

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

.h content:

#ifndef _LIBFTS
# define _LIBFTS

#include <stddef.h>

int         ft_isascii(int c);


ft_isascii.s content:

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

I would REALLY be thanksful for any tips to solve this issue...


fuz Reply to 2018-01-12 21:07:06Z

There are two problems to be fixed:

First, on ELF targets (most Unixes except macOS), C functions are not decorated with an underscore. 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. 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. These symbols are only needed once the linker has seen maintest.o. To fix this issue, move the $(NAME) operand to after $(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. Don't depend on this behaviour, please.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.340024 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO