簡體   English   中英

關於 Makefile 的建議並使用 C 庫構建系統結構

[英]Advice on Makefile and build system structure with a C library

我想要達到的目標:

我有一個庫,其中包含相互依賴的子模塊。

我想為每個子模塊創建一個 Makefile,然后將這些子模塊與存儲庫根目錄中的另一個 Makefile 合並到 one.a 文件中。 子模塊位於其 won 文件夾中,並將將 .o 文件編譯到其 won obj 目錄中。

我現在擁有的

Makefile 結合了以下庫:

NAME        =   libcore.a

HEADERS     =   arr/inc mem/inc str/inc map/inc
FOLDER      =   src
MEM         =   mem
ARR         =   arr
STR         =   str
MAP         =   map

MEM_O       =   $(wildcard mem/obj/*.o)
ARR_O       =   $(wildcard arr/obj/*.o)
STR_O       =   $(wildcard str/obj/*.o)
MAP_O       =   $(wildcard map/obj/*.o)
OBJ         =   $(MEM_O) $(ARR_O) $(STR_O) $(MAP_O)
RM          =   rm -f


all: $(OBJ)
            @make -C $(MEM)
            @make -C $(ARR)
            @make -C $(STR)
            @make -C $(MAP)
            @ar -rcs $(NAME) $(OBJ)
            @echo "\\n\033[32;1mCORE ACTIVATED \033[0m \\n"

clean:
            @make clean -C $(MEM)
            @make clean -C $(ARR)
            @make clean -C $(STR)
            @make clean -C $(MAP)
            @echo "\\n\033[32;1mCORE DEACTIVATED \033[0m \\n"

fclean:     clean
            @${RM} ${NAME}
            @make fclean -C $(MEM)
            @make fclean -C $(ARR)
            @make fclean -C $(STR)
            @make fclean -C $(MAP)

re:         fclean all

.PHONY:     all fclean clean re

Makefile 用於單個子模塊:

NAME        =   libarr.a

CC          =   clang
CFLAGS      =   -O3 -Wall -Wextra -Werror -Wpedantic -Wtype-limits \
                -Wunreachable-code -Wpadded -Wshadow -fPIC -Wconversion
SRC_DIR     =   src/
INC_DIR     =   inc/
OBJ_DIR     =   obj/

SRC_BASE    =   arr_add.c \
                arr_add_first.c \
                arr_add_last.c \
                arr_add_mult.c \
                arr_new.c \
                arr_put.c \
                arr_free.c \
                arr_del.c \
                arr_del_first.c \
                arr_del_last.c \
                arr_get.c \
                arr_get_first.c \
                arr_get_last.c \
                arr_iter.c \
                arr_iter_range.c \
                arr_join.c \
                arr_read_file.c \
                arr_take.c \
                arr_take_first.c \
                arr_take_last.c \
                arr_search.c \
                arr_find.c \
                arr_parse.c \
                arr_write.c \
                arr_null.c \
                arr_grow.c \
                arr_copy.c \
                arr_rotate.c \

SRC         =   $(addprefix $(SRC_DIR), $(SRC_BASE))
OBJ         =   $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))

all:
                $(MAKE) -j $(NAME)

$(NAME): $(OBJ)
                @echo "\\n\033[32;1mARRAY FUNCTIONS COMPILED\033[0m \\n"

$(OBJ_DIR):
                @mkdir -p $@

$(OBJ_DIR)%.o: $(SRC_DIR)%.c | $(OBJ_DIR)
                @$(CC) $(CFLAGS) -c $< -o $@ -I $(INC_DIR)

clean:
                @rm -rf $(OBJ_DIR);


fclean: clean
                @rm -rf $(NAME);

re: fclean all

.PHONY: all fclean clean re

問題

測試程序編譯:

gcc -fsanitize=undefined -fsanitize=address -fsanitize=leak arr/tests/tests.c libcore.a

我的設置有問題。 當我為主 Makefile 運行一次時,linker 不會在數組庫中找到函數並給出未定義的引用。 但是,當我第二次運行 Make 時,我可以正確編譯我的測試程序。 我只是不知道我做錯了什么。 我的想法是我在子模塊 Makefiles 中創建.o 文件,然后基本上將所有這些.o 文件與主 Makefile 編譯成 one.a 文件。

提前感謝您對此的任何幫助!

您看到的錯誤的直接原因在這里,主要是 makefile:

MEM_O       =   $(wildcard mem/obj/*.o)

這為您提供了在變量MEM_O展開時存在的所有 object 文件的列表,這發生Make 執行任何規則之前。 所以在第一次通過時變量是空的(因為沒有 object 文件),子 make 構建 object 文件,而主 Make 沒有放入庫中(因為變量是空的)。

最嚴重的錯誤是您在沒有經過充分測試的情況下編寫了所有這些 Makefile。 當你編寫代碼時,你應該從一些可以完美運行的小而簡單的東西開始,然后構建。 (我現在真的應該有那個熱鍵了。)

中級錯誤是遞歸 Make 很笨拙。 它有它的用途,但如果你不小心處理它,你會得到這樣的錯誤。 我建議使用頂級 makefile 包括較低的 makefile(通過include指令),以及可以在任一級別 function 的較低級別的 makefile。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM