Por padrão, todo projeto no Visual Studio depende da LIBC. Isso quer dizer que, mesmo que você não use nem um mísero printf em todos os projetos criados, está atrelado a essa dependência. Em tempos onde fazer um "Hello World" pode custar 56 KB em Release - Visual Studio 2005, configuração padrão sem "buffer security check" - vale a pena economizar alguns KBytes que não se vão usar. Principalmente se essa possibilidade existe desde o cavernoso Windows 95.
Como fazer um projeto de Hello World
- Crie um novo projeto console Win32 vazio (File, New, Project, blá blá blá)
- Crie um arquivo CPP no projeto (Project, Add New Item, etc)
- Crie um código parecido com o código abaixo (parecido == usando apenas LIBC básica)
- Troque a configuração para Release, pois Debug não tem graça (Build, Configuration Manager, Release)
- Mude a runtime para estática (Project, Properties, C/C++, Code Generation, Multi-threaded)
- Compile e link (Build, Build Solution)
#define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <string.h> int main() { printf("oi, mundo!"); }
Pronto, após esses passos temos um projeto ordinário que compila um executável console ordinário que não depende de runtimes novas com exatos (pelo menos aqui) 57.344 bytes.
Agora a parte divertida =).
Como gerar um .LIB de uma DLL de terceiros
Desde o Windows 95, existe uma DLL com a maioria das funções da LIBC disponíveis para link dinâmico. Só que, com o uso padrão do Visual C++, é usada sempre a biblioteca que vem junto com o ambiente, com suas trocentas funções (e conseqüentes bytes enche-lingüiça). Porém, é possível utilizar diretamente a msvcrt.dll distribuída no diretório do sistema se criarmos uma LIB de importação para ela.
- Copie a msvcrt.dll diretamente de um Windows 95 (diretório System) para evitar funções que não existam desde a primeira distribuição
- Utilizando essa versão da DLL e o prompt de comando do Visual Studio, execute:
REM REM Isso gera um arquivo def em estado bruto REM DUMPBIN /EXPORTS msvcrt.dll > msvcrt.def
- Utilizando o editor do seu coração, retire as linhas desnecessárias (aquelas do início do comando)
- Retire as colunas desnecessárias (todas menos a com o nome das funções)
- Retire os nomes bizarros que você não vai usar (todos os primeiros e que começam com '?')
- Ainda no ambiente console do VC execute o seguinte comando:
REM REM Isso gera um arquivo .lib para importar as funções da DLL REM LIB /DEF:msvcrt.def
Nada nessa mão, nem nessa. Mas no system32...
Ótimo. Geramos a LIB que precisávamos e agora só falta integrar com o projeto. Para isso, mais alguns passos:
- Copie o msvcrt.lib para o diretório do projeto.
- No projeto, coloque o arquivo na lista de LIBs a serem incluídas (Properties, Linker, Input, Additional Dependencies).
- Ignore o resto das LIBs colocadas por padrão no projeto (Linker, Input, Ignore All Default Libraries).
- Ignore as firulas de checagem (C/C++, Code Generation, Buffer Security Check, e Basic Runtime Checks em Debug).
- Explicite o entry-point para a função main (Linker, Advanced, Entry Point).
- Compile e linke!
------ Rebuild All started: Project: NativeC, Configuration: Release Win32 ------ Deleting intermediate and output files for project 'NativeC', configuration 'Release|Win32' Compiling... NativeC.cpp Linking... Generating code Finished generating code Embedding manifest... Build Time 0:00 Build log was saved at "file://c:ProjectsTempNativeCReleaseBuildLog.htm" NativeC - 0 error(s), 0 warning(s) ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ========== Size: 2.944 bytes.
E agora o tamanho final de nosso executável passou para espantosos 2KB! Isso a princípio parece ótimo e dá vontade de usar em todos os projetos, mas existe um porém ainda não resolvido: as limitações da falta de um runtime. Para isso que existe a próxima seção.
Disclaimer
Essa é uma solução bem bobinha que não tem nada a ver com uma solução profissional 100% garantida e com suporte técnico 24 horas. Algumas coisas não vão funcionar, como inicialização de variáveis estáticas, exceções, redirecionamento de entrada/saída, etc. Contudo, para projetos simples e pequenos, isso não deverá ser um problema. No entanto, eu não garanto qualquer coisa que advier de compilações inspiradas neste artigo.

April 15th, 2008 at 10:27 pm
Recentemente encontrei isso, acho q tem a v
http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/
http://nn1234.wordpress.com/2008/04/11/vc-90-msvcrtdll-windows-95/
April 16th, 2008 at 6:49 pm
Testei o metodo do Koby e funciona muito bem, como Koby menciona em seu site, eh bem menos sujeito a erros para programas mais complexos, estou usando em compilações em modo release, em debug mode continuo com o msvcr90d.dll do Visual C++ 2008. Vinculação à msvcp que contém C++ stuff como STL não é possivel de forma dinâmica utilizando o mesmo método, se for seguidos os passos do WDK é possível a vinculação estática. A seguir os procedimentos que usei para poder usar a crt dinâmica + stl estática:
Additional Include Directories:
C:\WinDDK\\inc\crt;C:\WinDDK\\inc\api;C:\WinDDK\\inc\api\crt\stl70
Preprocessor Definitions
WIN32;NDEBUG;_CONSOLE;_STATIC_CPPLIB;_STL70_
Additional Library Directories
C:\WinDDK\\lib\crt\i386;C:\WinDDK\\lib\w2K\i386
Generate Manifest
No
Additional Dependencies
msvcrt_win2000.obj ntstc_msvcrt.lib msvcprt_btowc.lib
April 17th, 2008 at 8:06 am
Desculpe a ignorância, mas quem é esse Koby? Tem algum linque para esse método?
[]s
April 17th, 2008 at 9:34 pm
errr, eu passei o link no primeiro comentario, num faz sentido o segundo sem o primeiro, mas tah aqui ele denovo:
Recentemente encontrei isso, acho q tem a v
http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/
http://nn1234.wordpress.com/2008/04/11/vc-90-msvcrtdll-windows-95/
April 17th, 2008 at 9:36 pm
ah, o primeiro naum tah aprovado ainda, deve ser por isso
October 28th, 2008 at 4:39 pm
Olá,
Com o parâmetro /MD do compilador é possível fazer isso sem a necessidade de criar uma lib.
-George
October 28th, 2008 at 9:03 pm
Olá, George.
O parâmetro /MD cria um projeto que depende da DLL de runtime do Visual Studio (a msvcXX.dll, sendo XX a versão atual). Esse artigo demonstra como criar um projeto que não dependa de nenhum tipo de LIB estática ou distribuída pelo Visual Studio. No entanto, os projetos compilados com essa solução passarão a depender da DLL de runtime localizada no diretório de sistema do próprio Windows.
[]s
November 13th, 2008 at 10:01 am
Olá,
Concordo com você, realmente desse jeito não irá depender de nenhuma LIB do Visual C, seja ela estática ou dinâmica.
Alêm do tamanho reduzido outra vantagem de se linkar de forma dinâmica é que uma eventual atualização no runtime beneficia todos os programas que utilizem essa DLL. De forma estática isso não é possível já que o conteúdo dos arquivos OBJ (archive members da LIB) é copiado para o módulo final.
A propósito, você trabalha com C/C++ em SP? Como que é o mercado ai nesse ramo? Tem muita demanda?
Valeu e o seu artigo ficou muito bom! Legal também é a LIBCTINY.LIB do Pietrek.
[]s
-George
November 13th, 2008 at 12:48 pm
Sim, trabalho atualmente em São Paulo, Brasil. O mercado? Não sou uma pessoa muito indicada para falar sobre isso, pois trabalhei até hoje apenas em dois lugares. O que ouvimos falar quase sempre no grupo de oportunidades C++ são de empregos para essa área, quase a maioria.
[]s