Reputation: 41
Iam getting error at 98th line and i dont understand why this error is happening.
makefile:98: *** mixed implicit and normal rules. Stop.
and below is the code line at 98th line
$(SRC_C_OBJS): | $(OBJ_DIR)
Below is the code where above variables are used:
OBJ_DIR = .\build
_C_SRCS = $(PROGRAM)_i.c \
test_$(PROGRAM).c
_ASM_SRCS = $(PROGRAM).S
_REF_C_SRCS = $(PROGRAM)_c.c \
test_$(PROGRAM).c
REF_OBJS = $(_REF_C_SRCS:%.c=$(REF_OBJ_DIR)\%.o)
SRC_C_OBJS = $(_C_SRCS:%.c=$(OBJ_DIR)\%.o)
SRC_ASM_OBJS = $(_ASM_SRCS:%.S=$(OBJ_DIR)\%.obj)
SRC_C_OBJS += $(OBJ_DIR)/subsys.o
$(EXEC): $(SRC_C_OBJS) $(SRC_ASM_OBJS)
$(LD) $(LDFLAGS) -o $@ $(SRC_C_OBJS) $(SRC_ASM_OBJS) $(LLIBS)
Upvotes: 1
Views: 587
Reputation: 100781
Make was developed on and works with UNIX and POSIX paths. POSIX paths don't have drive specs (C:
etc.) and they use forward slash (/
) not backslash as directory separators. Make was not designed for and doesn't so work well with native Windows paths (drive specs and backslashes).
In particular, make often treats the :
in a drive spec as part of a rule definition (note how in a rule definition the :
separates the target from the prerequisites). It also follows the standard UNIX/POSIX convention that backslash is used for escaping special characters (at least in some places).
So. First, when asking questions on StackOverflow be sure to include critical details such as (a) what operating system you're using and (b) what version of the tool (in this case make) you're using.
Second, the example you gave above is missing absolutely crucial details: you did not include the assignment to the REF_OBJ_DIR
or PROGRAM
variables. Without this we cannot be sure exactly what the problem is.
In general when writing makefiles you should avoid using drive specs and you should use forward slashes not backslashes as directory separators. Most Windows programs will accept forward slashes (only certain old command.com
programs won't). If you must use drive specs, you'll need to get a version of make which is compiled to understand Windows paths.
One other thing, just to head off another common problem: make does not work well with paths containing spaces... so avoid them.
Upvotes: 1
Reputation: 140880
REF_OBJS = $(_REF_C_SRCS:%.c=$(REF_OBJ_DIR)\%.o) SRC_C_OBJS = $(_C_SRCS:%.c=$(OBJ_DIR)\%.o) SRC_ASM_OBJS = $(_ASM_SRCS:%.S=$(OBJ_DIR)\%.obj)
The \%
is escaping the %
, so it is interpreted as a literal %
, not as the substituted string. The /
is the directory separator on unix platforms, not \
. You want:
OBJ_DIR = ./build
REF_OBJS = $(_REF_C_SRCS:%.c=$(REF_OBJ_DIR)/%.o)
SRC_C_OBJS = $(_C_SRCS:%.c=$(OBJ_DIR)/%.o)
SRC_ASM_OBJS = $(_ASM_SRCS:%.S=$(OBJ_DIR)/%.obj)
Theoretically, if \
would be the separator, you could do:
REF_OBJS = $(_REF_C_SRCS:%.c=$(REF_OBJ_DIR)\\%.o)
SRC_C_OBJS = $(_C_SRCS:%.c=$(OBJ_DIR)\\%.o)
SRC_ASM_OBJS = $(_ASM_SRCS:%.S=$(OBJ_DIR)\\%.obj)\
Upvotes: 1