GNU make conditional function $(if ...) inside a user-defined function always evaluates to true

$(if ...) conditional function evaluates to true when the first argument passed to it is non-empty. In you case the condition is literal text: ifeq "foo" "bar", which is, obviously, non-empty.

ifeq/ifneq conditionals are in fact directives, not functions. They can't be used inside variable definition and in functions.

Back to your example, to test string for equality inside the condition use functions like filter and findstring:

$(if $(filter foo,bar),@echo match is broken,@echo match works)
$(if $(filter-out foo,bar),@echo match works,@echo match is broken)

BTW this could be also turned into an inline form for better readability:

@echo match $(if $(filter foo,bar),is broken,works)
@echo match $(if $(filter-out foo,bar),works,is broken)

I faced this problem and I found you can use the result of "filter" function in the "condition" part of "if" function. Here is an example useful for opening a pdf either in Linux (with "evince"), or in OSX with "open")

uname     :=$(shell uname -s)
is_darwin :=$(filter Darwin,$(uname))
viewpdf   :=$(if $(is_darwin), open, evince)

You seem to be misunderstanding the way $(if works. From the make info docs:

$(if CONDITION,THEN-PART[,ELSE-PART])' The `if' function provides support for conditional expansion in a functional context

The first argument, CONDITION, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.

In all your examples, your condition is something like ifeq SOMETHING OTHERTHING -- which is a non-empty string (from the ifeq irrespective of what the other things are), and so is treated as true.