Home > Blockchain >  Makefile:30: recipe for target 'obj/main.o' failed
Makefile:30: recipe for target 'obj/main.o' failed

Time:11-12

I'm trying to use the makefile on windows, it seems not to be very common to use Makefile on Windows, so I followed some steps installing MingW, which is used for compilation, but when running make, this error occurred:

  mkdir -p ./obj/ 
    The command syntax is incorrect. 
    Makefile:30: recipe for target 'obj/main.o' failed 
    mingw32-make.exe: *** [obj/main.o] Error 1

Here's the code:

NAME            = minishell
LIBFT           = libft.a

CC              = cc 
CF              = -g -Wall -Wextra -Werror
CFI             = -I $(INCLUDE)
CREADLINE       = -lreadline

LIBFT_PATH      = ./libs/libft/
SRC_PATH        = ./sources/
OBJ_PATH        = ./obj/
INCLUDE         = ./includes/

SRC             = main.c\
                  prompt.c\
                  exec.c pipe.c paths.c command.c\
                  utils_pipes.c\
                  signals.c\

VPATH           := $(SRC_PATH)\
                $(SRC_PATH)prompt\
                $(SRC_PATH)execute\
                $(SRC_PATH)utils\

OBJ             = $(addprefix $(OBJ_PATH), $(notdir $(SRC:.c=.o)))

RM              = rm -rf

$(OBJ_PATH)%.o: %.c
                mkdir -p $(OBJ_PATH)
                $(CC) $(CF) $(CFI) -c $< -o $@

$(NAME):        $(OBJ)
                make -C $(LIBFT_PATH) $(LIBFT)
                $(CC) -g $(CF) -I $(INCLUDE) -o $(NAME) $(OBJ) -L $(LIBFT_PATH) -lft $(CREADLINE)
                @echo "$(GREEN)$(NAME) created$(DEFAULT)"

all:            $(NAME)

re:             fclean all

clean:
                make -C $(LIBFT_PATH) clean
                $(RM) $(OBJ) $(OBJDIR)
                @echo "$(YELLOW)object files deleted$(DEFAULT)"

fclean:         clean
                make -C $(LIBFT_PATH) fclean
                $(RM) $(NAME)
                @echo "$(RED)all deleted$(DEFAULT)"

install:        
                sudo apt-get install -y libreadline-dev valgrind

leak:                           
                valgrind --suppressions=readline.supp --leak-check=full --track-origins=yes --show-leak-kinds=all ./$(NAME)

.PHONY:         all clean fclean re bonus rebonus

#COLORS
RED = \033[1;31m
GREEN = \033[1;32m
YELLOW = \033[1;33m
DEFAULT = \033[0m`

Could anyone give an idea how to fix this?

CodePudding user response:

A makefile contains two different types of text. There is makefile syntax, which is parsed by make. This is all the text in the makefile which is not indented with a TAB character. The syntax for this is described in the make documentation.

Then there is shell script syntax, which is not parsed by make. This is all the text that is indented by a TAB character. This text is not handled by make; instead make invokes a shell program to run these commands.

On a POSIX-based system such as GNU/Linux, MacOS, the *BSD systems, etc., they all use the same basic shell and set of utilities as defined by the POSIX standard. mkdir -p is a POSIX command plus option, directories are separated by forward-slash, and everything works nicely.

The make utility was created in the 1970's on a UNIX (POSIX-base) system and appears on every POSIX systems since.

On Windows, the world is very different. The tools (like mkdir) work differently on Windows, the paths are constructed differently ("drive letters", backslashes for separators, etc.), there are multiple shells (cmd.exe and PowerShell) and none of these shells work the same way as the POSIX standard.

All this to say, it's very tricky to write a single makefile that will work on both POSIX and Windows environments because they are very very different.

Your options are (a) install a POSIX environment on you Windows system and run make from there using all POSIX tools, or (b) use make variables to hold different commands based on the OS type you're using, so that your rules can be portable.

In your makefile, it is invoking the Windows cmd.exe shell, which is trying to run the Windows mkdir program, which does not understand the POSIX -p option. So you get this error.

CodePudding user response:

First: Make expects as first character of a command a real tab ('\t'), not blanks (' ').

Enable your editor to show you white space character and check this.

You can put blanks or more tabs after the initial tab, if you need to.


Anyway, this seems not to be the core issue.

Your Makefile is using command lines for another shell than CMD. You need to adjust them to the other syntax.

For example, unixoid operating systems know the command "mkdir", which allows the option "-p" to create all directories on the way to the final one, if they do not exist. This is for safety reasons. CMD's version of "mkdir" does not know this option, beside the fact that it does not accept forward-slashes as path separators.

  • Related