有没有办法用一个Makefile一个一个编译一堆C源码?

Is there a way to compile a bunch of C source code one by one with a Makefile?

我创建了一个 Makefile 以及一些 C 源代码文件和一个头文件 (.h)。

NAME = libft.a

SRCS = ft_isalnum.c ft_isalpha.c ft_isascii.c ft_isdigit.c ft_isprint.c ft_strlen.c ft_bzero.c ft_memcpy.c ft_memset.c ft_memmove.c ft_strlcpy.c ft_strlcat.c ft_toupper.c ft_tolower.c ft_strchr.c ft_strrchr.c ft_strncmp.c ft_memchr.c ft_memcmp.c ft_strnstr.c ft_atoi.c ft_calloc.c ft_strdup.c ft_substr.c ft_strjoin.c ft_strtrim.c ft_split.c ft_itoa.c ft_strmapi.c ft_striteri.c ft_putchar_fd.c ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c

SRC_BONUS = ft_lstnew.c ft_lstadd_front.c ft_lstsize.c ft_lstlast.c ft_lstadd_back.c ft_lstdelone.c ft_lstclear.c ft_lstiter.c ft_lstmap.c

OBJECTS = $(SRCS:.c=.o)

OBJ_BONUS = $(SRC_BONUS:.c=.o)

CFLAGS = -Wall -Wextra -Werror

all: $(NAME)

$(NAME): $(OBJECTS)
        ar rc $(NAME) $(OBJECTS)

$(OBJECTS): $(SRCS)
        gcc $(CFLAGS) -c $(SRCS)

$(OBJ_BONUS): $(SRCS) $(SRC_BONUS)
        gcc $(CFLAGS) -c $(SRCS) $(SRC_BONUS)

bonus: $(OBJECTS) $(OBJ_BONUS)
        ar rc $(NAME) $(OBJECTS) $(OBJ_BONUS)

我必须用那些 C 源代码文件创建目标文件,然后使用这些目标文件创建静态库 (.a)。

所以,我想知道是否有一种方法可以将每个源代码文件一个一个地编译,而不是一次编译所有这些文件?

gcc -Wall -Wextra -Werror -c ft_isalnum.c ft_isalpha.c ft_isascii.c ft_isdigit.c ft_isprint.c ft_strlen.c ft_bzero.c ft_memcpy.c ft_memset.c ft_memmove.c ft_strlcpy.c ft_strlcat.c ft_toupper.c ft_tolower.c ft_strchr.c ft_strrchr.c ft_strncmp.c ft_memchr.c ft_memcmp.c ft_strnstr.c ft_atoi.c ft_calloc.c ft_strdup.c ft_substr.c ft_strjoin.c ft_strtrim.c ft_split.c ft_itoa.c ft_strmapi.c ft_striteri.c ft_putchar_fd.c ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c

一次编译每个源代码文件和一个一个编译是一回事吗?

库显然不会发生这种情况,我只需要一个静态库就可以拥有所有这些功能,所以我必须使用所有目标文件来创建它。

gcc -Wall -Wextra -Werror -c ft_isalnum.c ft_isalpha.c ft_isascii.c ft_isdigit.c ft_isprint.c ft_strlen.c ft_bzero.c ft_memcpy.c ft_memset.c ft_memmove.c ft_strlcpy.c ft_strlcat.c ft_toupper.c ft_tolower.c ft_strchr.c ft_strrchr.c ft_strncmp.c ft_memchr.c ft_memcmp.c ft_strnstr.c ft_atoi.c ft_calloc.c ft_strdup.c ft_substr.c ft_strjoin.c ft_strtrim.c ft_split.c ft_itoa.c ft_strmapi.c ft_striteri.c ft_putchar_fd.c ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c

是的,这是可能的。

像这样

SRC += $(wildcard src/*.c)

OBJECTS += $(SRC:%.c=%.o)

INCLUDE += -Iinclude

NAME = test

binary: $(OBJECTS)
    gcc -o $(NAME) $(OBJECTS)

%.o: %.c
    gcc -o $@ -c $< $(INCLUDE)

当然,您必须根据您的 makefile 进行调整。

关键部分是每个*.o执行的最后一个目标(每个*.o都依赖于它的*.c文件,所以这个*.o只有在它比*.o旧时才会被编译。 c文件)。 在具有两个文件 main.cother.c 的项目中调用该 makefile 的输出可能如下所示:

>$ make binary 
gcc -o src/other.o -c src/other.c -Iinclude
gcc -o src/main.o -c src/main.c -Iinclude
gcc -o test src/other.o src/main.o

您可以在此处找到一些可能对您有所帮助的提示:
http://nuclear.mutantstargoat.com/articles/make/

PS:

我建议使用源和包含目录(通常为“src”和“include”)和输出目录(“build”或“out”在这里很常见)。让您的生活和 makefile 更轻松。

使用CMake的解决方案:

首先,创建一个 CMakeLists.txt 文件:

cmake_minimum_required ( VERSION 3.10 )
project ( MyWonderfulProject )
file ( GLOB MySources *.c )
add_library ( MyWonderfulProject STATIC ${MySources} )

然后创建构建目录:

$ mkdir build
$ cd build

然后从 CMake 指令创建一个 Makefile 并编译:

$ cmake ..
$ make

瞧瞧!