【问题标题】:Makefile - compiling library and executable when no changes madeMakefile - 在未进行任何更改时编译库和可执行文件
【发布时间】:2017-04-20 20:57:01
【问题描述】:

所以,我可以理解这里的问题是什么,但我不知道如何解决它——因为它是从不同的目录编译文件,但是将 .a 库文件和可执行文件放入根目录...似乎 makefile 期望它们位于其源目录中,这就是为什么即使没有进行任何更改,它也会每次都重新构建。

问题是,我的学校对文件夹结构非常严格,所以它需要准确编译,我只需要弄清楚如何让makefile知道根目录下的可执行文件和库文件确实存在。

这是我的 Makefile:

NAME = fillit
LIB = libft.a

CC = gcc
CFLAGS = -Wall -Wextra -Werror
RM = /bin/rm -rf

SRC = main.c validation.c create_piece.c game_board.c solver.c tables.c \
    trimmer.c

LIBSRC = ft_putchar.c ft_putstr.c ft_strcpy.c ft_strnew.c ft_strdel.c \
    ft_strequ.c ft_putendl.c ft_error.c

LIBLIST  :=  $(shell ls -1 libft | grep .c$$)
LIBOBJ   :=  $(LIBLIST:.c=.o)
LIBOBJ   :=  $(addprefix libft/, $(LIBOBJ))

SRCLIST  :=  $(shell ls -1 src | grep .c$$)
SRCOBJ   :=  $(SRCLIST:.c=.o)
SRCOBJ   :=  $(addprefix src/, $(SRCOBJ))

.PHONY: all $(NAME) lib

all: $(NAME)

libft/%.o: libft/%.c
    $(CC) $(CFLAGS) -c -o $@ $<

src/%.o: src/%.c
    $(CC) $(CFLAGS) -c -o $@ $<

lib:
    ar rc $(LIB) $(LIBOBJ)
    ranlib $(LIB)

debug:
    $(CC) $(CFLAGS) $(addprefix libft/, $(LIBLIST)) $(addprefix src/, $(SRCLIST)) -g -o fillit

$(NAME): $(LIBOBJ) $(SRCOBJ) lib
    $(CC) $(CFLAGS) $(SRCOBJ) -L. -lft -o fillit

clean:
    $(RM) $(SRCOBJ)
    $(RM) $(LIBOBJ)


fclean: clean
    $(RM) $(NAME)
    $(RM) $(LIB)

re: fclean all

re-db: fclean debug

编译.o文件没问题,它只做一次,但如果我继续输入make,它仍然编译这部分:

➜  fillit git:(master) ✗ make
ar rc libft.a libft/ft_memset.o libft/ft_putchar.o libft/ft_putendl.o libft/ft_putstr.o libft/ft_strcpy.o libft/ft_strdel.o libft/ft_strequ.o libft/ft_strnew.o
ranlib libft.a
gcc -Wall -Wextra -Werror src/create_piece.o src/game_board.o src/main.o src/solver.o src/tables.o src/trimmer.o src/validation.o -L. -lft -o fillit

【问题讨论】:

  • 您的lib 目标没有依赖关系,因此它始终运行。
  • 还有正在生成的可执行文件呢?
  • 嗯,它取决于总是需要重建的 lib,导致 exec 目标总是被重建。
  • 我尝试将 $(LIB) 添加为依赖项,但这不起作用。我想我仍然对依赖项的确切工作方式有些困惑。我一直在阅读它,但我无法弄清楚我做错了什么。
  • 我已通过将 lib 更改为 $(LIB) 来修复库编译问题——尽管它仍在编译可执行文件。

标签: c gcc makefile


【解决方案1】:

要感谢 kaylum 为我指明了正确的方向,我已经想出了如何解决这个问题。我将 lib 更改为 $(LIB) 并从虚假列表中删除了 $(NAME) 和 lib。工作生成文件:

NAME = fillit
LIB = libft.a

CC = gcc
CFLAGS = -Wall -Wextra -Werror
RM = /bin/rm -rf

SRC = main.c validation.c create_piece.c game_board.c solver.c tables.c \
    trimmer.c

LIBSRC = ft_putchar.c ft_putstr.c ft_strcpy.c ft_strnew.c ft_strdel.c \
    ft_strequ.c ft_putendl.c ft_error.c

LIBLIST  :=  $(shell ls -1 libft | grep .c$$)
LIBOBJ   :=  $(LIBLIST:.c=.o)
LIBOBJ   :=  $(addprefix libft/, $(LIBOBJ))

SRCLIST  :=  $(shell ls -1 src | grep .c$$)
SRCOBJ   :=  $(SRCLIST:.c=.o)
SRCOBJ   :=  $(addprefix src/, $(SRCOBJ))

.PHONY: all

all: $(NAME)

libft/%.o: libft/%.c
    $(CC) $(CFLAGS) -c -o $@ $<

src/%.o: src/%.c
    $(CC) $(CFLAGS) -c -o $@ $<

$(LIB):
    ar rc $(LIB) $(LIBOBJ)
    ranlib $(LIB)

debug:
    $(CC) $(CFLAGS) $(addprefix libft/, $(LIBLIST)) $(addprefix src/, $(SRCLIST)) -g -o fillit

$(NAME): $(LIBOBJ) $(SRCOBJ) $(LIB)
    $(CC) $(CFLAGS) $(SRCOBJ) -L. -lft -o $(NAME)

clean:
    $(RM) $(SRCOBJ)
    $(RM) $(LIBOBJ)


fclean: clean
    $(RM) $(NAME)
    $(RM) $(LIB)

re: fclean all

re-db: fclean debug

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多