#inclui todos os arquivos .cpp em uma única unidade de compilation?

Recentemente tive motivos para trabalhar com alguns projetos Visual Studio C ++ com as configurações usuais de Depuração e Liberação, mas também com ‘Liberar Todos’ e ‘Depurar Todos’, o que eu nunca havia visto antes.

Acontece que o autor dos projetos tem um único ALL.cpp que #inclui todos os outros arquivos .cpp. O * Todas as configurações apenas constroem este arquivo ALL.cpp. É claro que é excluído das configurações regulares, e configurações regulares não constroem ALL.cpp

Eu só queria saber se isso era uma prática comum? que benefícios isso traz? (Minha primeira reação foi que cheirava mal.)

Que tipos de armadilhas você provavelmente encontrará? Uma coisa em que posso pensar é se você tem namespaces anônimos em seus .cpps, eles não são mais ‘privados’ para esse cpp, mas agora são visíveis em outros CPPs também?

Todos os projetos criam DLLs, portanto, ter dados em namespaces anônimos não seria uma boa ideia, certo? Mas as funções seriam OK?

Felicidades.

É referido por alguns (e google-capaz) como um “Build Unity”. Liga-se incrivelmente rápido e compila razoavelmente rápido também. É ótimo para construções que você não precisa fazer uma iteração, como uma compilation de release de um servidor central, mas não é necessariamente para criação incremental.

E é um PITA para manter.

EDIT: aqui está o primeiro link do google para mais informações: http://buffered.io/posts/the-magic-of-unity-builds/

O mais rápido é que o compilador só precisa ler tudo uma vez, compilar, depois vincular, em vez de fazer isso para cada arquivo .cpp.

Bruce Dawson escreveu muito melhor sobre isso em seu blog: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/

O Unity constrói velocidades de construção aprimoradas por três razões principais. A primeira razão é que todos os arquivos de header compartilhados precisam ser analisados ​​apenas uma vez. Muitos projetos C ++ têm muitos arquivos de header que são incluídos pela maioria ou todos os arquivos CPP e a análise redundante destes é o custo principal da compilation, especialmente se você tiver muitos arquivos de origem curtos. Arquivos de header pré-compilados podem ajudar com esse custo, mas geralmente há muitos arquivos de header que não são pré-compilados.

O próximo motivo principal pelo qual as builds de unidade melhoram as velocidades de construção é porque o compilador é invocado menos vezes. Há algum custo inicial com a chamada do compilador.

Finalmente, a redução na análise de header redundante significa uma redução na geração de código redundante para funções embutidas, portanto, o tamanho total dos arquivos de object é menor, o que torna a vinculação mais rápida.

As construções de unidades também podem fornecer uma melhor geração de código.

As construções de unidades NÃO são mais rápidas devido à redução de E / S de disco. Eu fiz muitos perfis com o xperf e sei do que estou falando. Se você tiver memory suficiente, o cache de disco do sistema operacional evitará a E / S redundante – as leituras subseqüentes de um header virão do cache de disco do sistema operacional. Se você não tiver memory suficiente, então as compilações de unidade podem até piorar o tempo de construção, fazendo com que o espaço ocupado pela memory do compilador exceda a memory disponível e seja paginado.

AE / S de disco é cara, e é por isso que todos os sistemas operacionais armazenam dados em cache de forma agressiva para evitar E / S de disco redundante.

Gostaria de saber se o ALL.cpp está tentando colocar todo o projeto dentro de uma única unidade de compilation, para melhorar a capacidade do compilador de otimizar o programa para o tamanho?

Normalmente, algumas otimizações são executadas apenas em unidades de compilation distintas, como a remoção de código duplicado e inline.

Dito isso, parece que lembro que compiladores recentes (da Microsoft, da Intel, mas acho que isso não inclui o GCC) podem fazer essa otimização em várias unidades de compilation, então suspeito que esse “truque” não seja necessário.

Dito isto, seria curioso ver se há realmente alguma diferença.

Eu concordo com Bruce; Pela minha experiência, tentei implementar o Unity Build para um dos meus projetos .dll, que tinha uma tonelada de headers e muitos .cpps; para reduzir o tempo total de compilation no VS2010 (já tinha esgotado as opções Incremental Build), mas em vez de reduzir o tempo de compilation, fiquei sem memory e o Build nem sequer conseguiu terminar a compilation.

No entanto, para adicionar; Eu descobri que ativar a opção de compilation de multiprocessadores no Visual Studio ajuda bastante na redução do tempo de compilation; Não tenho certeza se essa opção está disponível em outros compiladores de plataforma.

Além da excelente resposta de Bruce Dawson, o seguinte link traz mais insights sobre os prós e contras dos builds de unidades – https://github.com/onqtam/ucm#unity-builds