Use -prune nos diretórios que você irá excluir de qualquer forma para informar find para não tentar encontrar arquivos neles:
find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +
Observe também que *.so precisa ser citado, caso contrário, pode ser expandido pelo shell para a lista de .so arquivos no diretório atual.
O equivalente do seu% GNU-regex -type seria:
find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +
Observe que, se você usar a sintaxe específica do GNU, também poderá usar -delete em vez de -exec rm -rf {} + . Com -delete , o% GNUfind ativa -depth automaticamente. Ele não executa comandos externos então, dessa forma, é mais eficiente, e também é mais seguro pois remove a condição de corrida onde alguém pode fazer com que você remova os arquivos errados alterando um diretório para um symlink entre as horas find encontra um arquivo e rm o remove (veja info -f find -n 'Security Considerations for find' para detalhes).
find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete