Bom, primeiro, compilar pode ser exlpicado como traduzir.
Um compilador nada mais faz que traduzir um código de uma linguagem para outra.
Comumente, a linguagem destino é código de máquina, ou seja, o executável.
Porém, existem compiladores que geram código intermediário, o compilador Java é um exemplo, já que a partir do código Java escrito pelo programador ele gera um código de bytes Java que é interpretado pela máquina virtual.
O makefile é um arquivo de configrações de compilação, feito pelo programador. Nele vem definidos quais arquivos devem ser compilados, como gerar o executável, etc.
Geralmente você precisa sim saber em qual linguagem seu código está escrito, pra você poder escolher o compilador apropriado. Você não pode compilar um código escrito em C++ usando um compilador que compila código Pascal por exemplo.
No entanto, é comum os programadores fornecerem junto com o código scripts para configuração e compilação automática. Assim você não precisa se preocupar com os detalhes e basta usar os conhecidos
./configure, make e make install.