Como faço um .exe totalmente vinculado estaticamente com o Visual Studio Express 2005?

109

Meu ambiente C ++ preferido atualmente é a edição gratuita e amplamente excelente do Microsoft Visual Studio 2005 Express. De vez em quando, envio arquivos .exe de lançamento para outras pessoas com resultados agradáveis. No entanto, recentemente fiz a descoberta perturbadora de que os resultados satisfatórios foram baseados em mais sorte do que eu gostaria. A tentativa de executar um desses programas em uma caixa XP antiga (vintage de 2001, não cuidadosamente atualizada) não me deu nada além de uma mensagem desagradável "O sistema não pode executar x.exe" (ou semelhante).

Algumas pesquisas no Google revelaram que, com esse conjunto de ferramentas, até mesmo a especificação de links estáticos resulta em um simples hello-world.exe, na verdade, contando com arquivos .dll extras (msvcm80.dll etc.). Um sistema de esquema de versões incrivelmente elaborado (arquivos de manifesto, alguém?) Não permitirá que o .exe seja executado sem exatamente as versões .dll corretas. Eu não quero ou preciso dessas coisas, eu só quero um antigo .exe autocontido que não faz nada além de operações Win32 de menor denominador comum e roda em qualquer sistema operacional win32 antigo.

Alguém sabe se é possível fazer o que quero fazer com meu conjunto de ferramentas existente?

Obrigado.

Bill Forster
fonte

Respostas:

126

Para o C-runtime vá para as configurações do projeto, escolha C / C ++ e então 'Code Generation'. Altere a configuração da 'biblioteca de tempo de execução' para 'multithreaded' em vez de 'dll multithreaded'.

Se você estiver usando qualquer outra biblioteca, pode ser necessário dizer ao vinculador para ignorar explicitamente o CRT vinculado dinamicamente.

Rob Walker
fonte
"Se você estiver usando qualquer outra biblioteca, pode ser necessário dizer ao vinculador para ignorar explicitamente o CRT vinculado dinamicamente." Recentemente me deparei com esse problema. Eu estava construindo um aplicativo wxWidgets, descobri que precisava reconstruir as bibliotecas wxWidgets com a mesma modificação de geração de código
Bill Forster
6
Homem, 300 caracteres não são muitos. Caso o comentário acima não esteja claro, o problema é que tanto seus arquivos .cpp quanto quaisquer arquivos .cpp de biblioteca precisam ter 'multithreaded' em vez de 'dll multithreaded', caso contrário, você poderá obter erros de link.
Bill Forster
Isso apresenta vários problemas relacionados ao gerenciamento de heap com os quais você provavelmente não deseja ter nada a ver.
Edward Strange
Para as bibliotecas CRT, o VS fornece as opções / MD e / MT. Mas, que tal vincular outras bibliotecas estaticamente em geral - digamos, libX.lib (que poderia ser minha própria biblioteca ou biblioteca de terceiros)?
Kiran MN
4
Eu entendo error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'. Existe algum outro lugar para alterar o tipo de construção? Estou construindo o aplicativo wxWigets, muito parecido com @BillForster. Então, terei que reconstruir wxWidgets? Como faço isso?
Tomáš Zato - Reintegração de Monica
18

Minha experiência no Visual Studio 2010 é que são necessárias duas alterações para não precisar de DLL's. Na página de propriedades do projeto (clique com o botão direito no nome do projeto na janela do Solution Explorer):

  1. Em Propriedades de configuração -> Geral, altere o campo "Uso de MFC" para "Usar MFC em uma biblioteca estática".

  2. Em Propriedades de configuração -> C / C ++ -> Geração de código, altere o campo "Biblioteca de tempo de execução" para "Multi-Threaded (/ MT)"

Não sei por que ambos eram necessários. Usei isso para remover uma dependência do glut32.dll.

Adicionado mais tarde: Ao fazer essas alterações nas configurações, você deve fazê-las em "Todas as configurações" --- você pode selecionar isso no topo da janela Propriedades. Se você alterar apenas a configuração de depuração, ela não se aplicará à configuração de lançamento e vice-versa.

Sam Buss
fonte
1
Isso parece funcionar no Visual Studio 2013 com uma pequena adição: Tive que alterar as Propriedades de configuração -> Geral -> Conjunto de caracteres para "Usar conjunto de caracteres Unicode".
gnovice
4

Eu tive esse mesmo problema de dependência e também sei que você pode incluir as DLLs do VS 8.0 (somente lançamento! Não depurar! --- e seu programa também deve ser lançado) em uma pasta com o nome apropriado, no pasta pai com seu .exe:

Como: implantar usando XCopy (MSDN)

Observe também que as coisas correrão mal se você precisar ter o código C ++ e C no mesmo .exe vinculado estaticamente, porque você obterá conflitos de vinculador que só podem ser resolvidos ignorando o libXXX.lib correto e vinculando dinamicamente (DLLs) .

Por último, com um conjunto de ferramentas diferente (VC ++ 6.0) as coisas "simplesmente funcionam", uma vez que o Windows 2000 e superior têm as DLLs corretas instaladas.

Jared Updike
fonte
1

Em relação à resposta de Jared, ter o Windows 2000 ou melhor não necessariamente resolverá o problema em questão. A resposta de Rob funciona, no entanto, é possível que essa correção introduza problemas de segurança, pois as atualizações do Windows não serão capazes de corrigir aplicativos criados como tal.

Em outra postagem, Nick Guerrera sugere empacotar o Visual C ++ Runtime Redistributable com seus aplicativos, que é instalado rapidamente e é independente do Visual Studio.

bunkerdive
fonte
2
Embora empacotar o redistribuível pareça ser a solução preferida, você precisa de privilégios de administrador para executar o instalador redistribuível. Essa não é uma opção viável se você tiver usuários que não sejam administradores.
Kevin Condon