Existem muitas razões para isso, e um pouco de história é para colocar as coisas em perspectiva.
Lembre-se de que, quando falamos em "Linux", geralmente nos referimos a uma das muitas distribuições Linux diferentes . "Linux" é na verdade apenas um kernel do sistema operacional.
O objetivo original do Linux era criar um sistema baseado em Unix que rodasse em PCs (inicialmente o 386). O primeiro passo foi criar o próprio kernel. Enquanto Linus Torvalds estava trabalhando no kernel, Richard Stallman estava trabalhando em seu próprio sistema Free Unix, sob o projeto GNU (GNU's Not Unix) . Para encurtar a história, os dois convergiram um pouco porque o GNU tinha os utilitários associados (compilador C / biblioteca / ferramentas de construção, shell, editores de texto etc.), mas não tinha núcleo para executá-lo, e o Linux tinha o núcleo, mas não tinha utilitários para correr em cima dele para torná-lo útil para as massas.
Essa convergência passou a ser conhecida oficialmente como GNU / Linux. Você verá que muitas distros ainda se referem a si mesmas como distribuições GNU / Linux.
Devido à natureza livre e aberta do GNU / Linux, qualquer um poderia buscá-lo e criar um sistema agrupado para seus gostos específicos. O resultado foi que muitos fluxos diferentes de métodos de configuração variados foram usados para criar esses sistemas, que tiveram o efeito colateral de criar quase tantos sistemas de gerenciamento de pacotes diferentes para se encaixarem em cada um.
Cada sistema completo diferente tinha seus próprios seguidores fortes que os mantiveram ao longo dos anos, resultando no que temos hoje: um punhado de sistemas de gerenciamento de pacotes amplamente usados, profundamente enraizados e estáveis, como RPM , APT / dpkg e Portage do Gentoo .
Existem projetos, como o Autopackage , que estão tentando resolver o problema, mas a evolução contínua dos vários sistemas de gerenciamento de pacotes suportados significa que existem muitos objetivos móveis a serem seguidos.
O que alguns fornecedores de software acabam fazendo é agrupar os binários e cópias específicos das dependências necessárias em um pacote grande que funcionará em sistemas específicos.