Компиляция исходников (cpp, cs) компилятором Visual Studio без запуска IDE в Windows
Частенько нет необходимости запускать тяжеловесную IDE Visual Studio для компиляции небольших приложений, проведения каких-либо тестов кода, не требующего полномасштабной отладки. В подобных случаях можно оперативно собрать приложение в консольном режиме, используя возможности предоставляемые компилятором от Microsoft (cl.exe) и запускными модулями IDE (devenv.exe, msdev.exe). Далее приводится код файлов сценариев (cmd) интерпретатора командной строки Windows, который с небольшими изменениями каждый может настроить под себя, с учётом путей к Visual Studio в своей системе.
Компиляция cpp-файлов
Код сценария vc++_compile_and_link.cmd
:: --------------------------------------------------------------------------- :: :: Перед использованием сценария рекомендуется задать системные переменные: :: :: sVSPath - путь к корневому каталогу Visual C++, :: :: sVSPathName - путь к основному исполнимому файлу Visual C++ :: :: (либо раскомментировать и отредактировать sVSPath, sVSPathName ниже в файле. :: --------------------------------------------------------------------------- :: echo off cls echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- :: -------------------------------------- :: :: Имена исходников (через пробел) :: :: -------------------------------------- :: set gavSrc=MySource1.cpp MySource2.cpp :: -------------------------------------- :: :: Дополнительно, если необходимо, для Qt :: :: - заголовочный файл,содержащий Q_OBJECT:: :: из него будет сгенерирован moc_xxx.cpp :: :: -------------------------------------- :: ::set gavSrcQtMoc=gavQtSignalSlot.h set gavSrcQtMoc="" :: -------------------------------------- :: :: Версия компилятора: :: :: 6 - VC6, :: :: 8 - VC8 (2005), :: :: 9 - VC9, :: :: 10 - VC10 (2010) :: :: 11 - VC11 (2012) :: :: -------------------------------------- :: set iCompVer=11 :: -------------------------------------- :: :: Режим компиляции: :: :: 0 - release, :: :: 1 - debug, :: :: 2 - генерирует прототипы функций :: :: (без компиляции) :: :: -------------------------------------- :: set iModeComp=1 :: -------------------------------------- :: :: Флаги наличия библиотеки: :: :: 0 - нет, 1 - есть :: :: -------------------------------------- :: set bLibQt=0 set bLibCrt=0 set bLibBoost=0 :: -------------------------------------- :: :: Режим линковки с Qt: :: :: 0 - shared (динамическая), :: :: 1 - static (статическая) :: :: -------------------------------------- :: set iModeQt=0 :: -------------------------------------- :: :: Флаги специальных WINDDK :: :: 0 - не используется :: :: 1 - WINDDK для Win2000, WinXP :: :: (в этом случае д.б. верно заданы:: :: gavIncPathDdkXP,gavLibPathDdkXP:: :: - см. ниже) :: :: -------------------------------------- :: set iWinddk=0 :: -------------------------------------- :: :: Дополнительные флаги компилятора :: :: ( дефайны задавать так: -Dдефайн ) :: :: -------------------------------------- :: ::set gavCompilFlags=-Dtest :: -------------------------------------- :: :: Подсистема приложения (одна из) :: :: -------------------------------------- :: :: Win32 character-mode application: set gavSubsystem=CONSOLE :: Application does not require a console: ::set gavSubsystem=WINDOWS :: Device drivers for Windows NT: ::set gavSubsystem=NATIVE :: Application that runs with the POSIX subsystem in Windows NT: ::set gavSubsystem=POSIX :: Application that runs on a Windows CE device: ::set gavSubsystem=WINDOWSCE :: -------------------------------------- :: :: Пути к Visual Studio. :: :: . без кавычек . :: :: -------------------------------------- :: :: VS6 (!! Путь к компилятору VS6 д.б. коротким и без пробелов - иначе ошибка линковки) if %iCompVer%==6 set sVSPath=C:\Progs\VC98 if %iCompVer%==6 set sVSPathName=%sVSPath%\bin\cl.exe :: VS8 if %iCompVer%==8 set sVSPath=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 8\VC if %iCompVer%==8 set sVSPathName=%sVSPath%\bin\cl.exe :: VS9 if %iCompVer%==9 set sVSPath=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 9.0\VC if %iCompVer%==9 set sVSPathName=%sVSPath%\bin\cl.exe :: VS10 if %iCompVer%==10 set sVSPath=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 10.0\VC if %iCompVer%==10 set sVSPathName=%sVSPath%\bin\cl.exe :: доп.пути для VS2010: if %iCompVer%==10 set gavIncPathMy=%SYSTEMDRIVE%\Program Files\Microsoft SDKs\Windows\v7.0A\Include if %iCompVer%==10 set gavLibPathMy=%SYSTEMDRIVE%\Program Files\Microsoft SDKs\Windows\v7.0A\Lib :: VS11 if %iCompVer%==11 set sVSPath=%SYSTEMDRIVE%\Program Files (x86)\Microsoft Visual Studio 11.0\VC if %iCompVer%==11 set sVSPathName=%sVSPath%\bin\cl.exe :: доп.пути для VS2010: if %iCompVer%==11 set gavIncPathMy=%SYSTEMDRIVE%\Program Files (x86)\Windows Kits\8.0\Include\um if %iCompVer%==11 set gavIncPathMy2=%SYSTEMDRIVE%\Program Files (x86)\Windows Kits\8.0\Include\Shared if %iCompVer%==11 set gavLibPathMy=%SYSTEMDRIVE%\Program Files (x86)\Windows Kits\8.0\Include\Lib if %iCompVer%==11 set gavLibPathMy2=%SYSTEMDRIVE%\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86 ::if %iCompVer%==11 set gavLibPathMy2=%SYSTEMDRIVE%\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64 echo Compilator version: VC%iCompVer% echo Compilator path: %sVSPathName% :: -------------------------------------- :: :: Пути к Boost :: :: -------------------------------------- :: set BOOST_ROOT=C:\Progs\boost\boost_1_49_0 :: -------------------------------------- :: :: Настройка путей к подключаемым :: :: файлам. Каждый путь должен быть :: :: отдельной переменной ! :: :: -------------------------------------- :: set gavIncPathVS="%sVSPath%\include" set gavIncPathQt="%QTDIR%\include" set gavIncPathBoost="%BOOST_ROOT%" set gavIncPathDdkCrt="C:\Progs\WINDDK\2600.1106\inc\crt" set gavIncPathDdkXP="C:\Progs\WINDDK\2600.1106\inc\w2k" if not "%gavIncPathMy%"=="" (set gavIncPathAll=-I"%gavIncPathMy%" if not "%gavIncPathMy2%"=="" ( set gavIncPathAll=-I"%gavIncPathMy%" -I"%gavIncPathMy2%" ) ) if %iWinddk%==1 (set gavIncPathAll=%gavIncPathAll% -I%gavIncPathDdkCrt% -I%gavIncPathDdkXP%) if not %gavIncPathVS%=="" (set gavIncPathAll=%gavIncPathAll% -I%gavIncPathVS%) if %bLibQt%==1 (if not %gavIncPathQt%=="" (set gavIncPathAll=%gavIncPathAll% -I%gavIncPathQt%)) if %bLibBoost%==1 (if not %gavIncPathBoost%=="" (set gavIncPathAll=%gavIncPathAll% -I%gavIncPathBoost%)) echo Include pathes: %gavIncPathAll% :: -------------------------------------- :: :: Настройка путей к библиотечным (.lib) :: :: файлам. Каждый путь должен быть :: :: отдельной переменной ! :: :: -------------------------------------- :: set gavLibPathDdkXP=C:\Progs\WINDDK\2600.1106\lib\wxp\i386 set gavLibPathVS=%sVSPath%\lib set gavLibPathAll="" if %iWinddk%==1 (set gavLibPathAll=%gavLibPathAll% /LIBPATH:"%gavLibPathDdkXP%") if not "%gavLibPathVS%"=="" (set gavLibPathAll=%gavLibPathAll% /LIBPATH:"%gavLibPathVS%") if not "%gavLibPathMy%"=="" (set gavLibPathAll=%gavLibPathAll% /LIBPATH:"%gavLibPathMy%" if not "%gavLibPathMy2%"=="" ( set gavLibPathAll=%gavLibPathAll% /LIBPATH:"%gavLibPathMy%" /LIBPATH:"%gavLibPathMy2%" ) ) set gavLibPathBoost="%BOOST_ROOT%\stage\lib" if %bLibBoost%==1 (if not %gavLibPathBoost%=="" (set gavLibPathAll=%gavLibPathAll% /LIBPATH:%gavLibPathBoost%)) set gavLibPathQtReleaseShared="%QTDIR%\lib\release\shared" set gavLibPathQtReleaseStatic="%QTDIR%\lib\release\static" set gavLibPathQtDebugShared="%QTDIR%\lib\debug\shared" set gavLibPathQtDebugStatic="%QTDIR%\lib\debug\static" if %bLibQt%==1 ( if %iModeComp%==0 ( if %iModeQt%==0 ( echo Qt mode: release shared set gavLibPathAll=%gavLibPathAll% /LIBPATH:%gavLibPathQtReleaseShared% ) if %iModeQt%==1 ( echo Qt mode: release static set gavLibPathAll=%gavLibPathAll% /LIBPATH:%gavLibPathQtReleaseStatic% ) ) if %iModeComp%==1 ( if %iModeQt%==0 ( echo Qt mode: debug shared set gavLibPathAll=%gavLibPathAll% /LIBPATH:%gavLibPathQtDebugShared% ) if %iModeQt%==1 ( echo Qt mode: debug static set gavLibPathAll=%gavLibPathAll% /LIBPATH:%gavLibPathQtDebugStatic% ) ) ) echo Lib pathes: %gavLibPathAll% :: -------------------------------------- :: :: Файлы библиотеки run-time. :: :: При необходимости добавить сюда нужные :: :: -------------------------------------- :: set gavLibFilesCrt="" if %bLibCrt%==1 (set gavLibFilesCrt=user32.lib ole32.lib Gdi32.lib Ws2_32.lib Imm32.lib Comdlg32.lib Winspool.lib Advapi32.lib) if not "%gavLibFilesCrt%"=="" (set gavLibFilesAll=%gavLibFilesCrt%) :: -------------------------------------- :: :: Файлы библиотеки Qt. :: :: -------------------------------------- :: set gavLibFilesQtShared=qtmain.lib qt-mt333.lib set gavLibFilesQtStatic=qtmain.lib qt-mt.lib if %bLibQt%==1 ( if %iModeQt%==0 (set gavLibFilesAll=%gavLibFilesAll% %gavLibFilesQtShared%) if %iModeQt%==1 (set gavLibFilesAll=%gavLibFilesAll% %gavLibFilesQtStatic%) ) echo Lib files: %gavLibFilesAll% :: -------------------------------------- :: :: Настройка режимов компиляции :: :: -------------------------------------- :: if %iModeComp%==0 ( set gavLinkMode=/RELEASE :: для DLL: set gavCompMode=/MD set gavCompMode=/MT set gavOptimize=/O2 /GA ) if %iModeComp%==1 ( set gavLinkMode=/DEBUG :: для DLL: set gavCompMode=/MDd set gavCompMode=/MTd ::set gavOptimize=/Od /ZI set gavOptimize=/Od /Z7 ) if %iModeComp%==2 ( set gavLinkMode= set gavCompMode= set gavOptimize=/Zg ) if %bLibQt%==1 (if %iModeQt%==1 (set gavCompMode=/MDd)) :: -------------------------------------- :: :: Настройка подсистемы приложения :: :: -------------------------------------- :: if not %gavSubsystem%=="" (set gavLinkSubsys=/SUBSYSTEM:%gavSubsystem%) :: -------------------------------------- :: :: Настройка компилятора :: :: -------------------------------------- :: if %bLibQt%==1 ( if %iModeQt%==0 (set gavCompilFlags=%gavCompilFlags% -DQT_DLL) ) :: -------------------------------------- :: :: Удаление старых файлов :: :: -------------------------------------- :: set gavOldObj=%gavSrc:.cpp=.obj,% set gavOldObj=%gavOldObj:.c=.obj,% set gavOldAsm=%gavOldObj:.obj=.asm% for /F "tokens=1" %%A in ("%gavSrc%") do (set gavMainName=%%A) set gavMainName=%gavMainName:.cpp=% set gavMainName=%gavMainName:.c=% set gavDelExt= %gavMainName%.exe, %gavMainName%.pdb, %gavMainName%.ilk, %gavOldObj% %gavOldAsm% __vc++_%gavMainName%.log echo. echo Deleting old files: %gavDelExt% . echo. del %gavDelExt% echo. echo ------------------ echo Compiling start. echo ------------------ echo. if %bLibQt%==1 (if not %gavSrcQtMoc%=="" ( echo ------------------ echo Mocing file. echo ------------------ echo on %QTDIR%\bin\moc %gavSrcQtMoc% -o moc_%gavSrcQtMoc%.cpp @echo off set gavSrc=%gavSrc% moc_%gavSrcQtMoc%.cpp )) echo on "%sVSPathName%" /EHsc %gavIncPathAll% %gavCompilFlags% /Fa %gavSrc% %gavCompMode% %gavOptimize% /link %gavLinkSubsys% %gavLinkMode% %gavLibPathAll% %gavLibFilesAll%>"__vc++_%gavMainName%.log" @echo off echo. echo ------------------ echo Compiling end. echo ------------------ echo. echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- :: -------------------------------------- :: pause
- sVSPath — путь к основному каталогу Visual Studio т.е. к корневому каталогу, в котором содержатся все прочие подкаталоги для данной версии VS.
- gavIncPathMy — возможно для VS 11.0 потребуется задать свои пути к подключаемым заголовочным файлам.
2) в разделе «Пути к Boost» можно задать BOOST_ROOT — путь к коревому каталогу библиотеки Boost (если она у вас установлена).
3) в разделе «Настройка путей к подключаемым файлам» при необходимости можно задать пути к заголовочным файлам Qt, WinDDK.
4) в разделе «Настройка путей к библиотечным (.lib) файлам» задаются пути к файлам библиотек (в частности для WinDDK).
Реже может возникнуть необходимость настроить следующие параметры под конкретный проект:
iCompVer — версия используемого компилятора (6 — для VC6, 8 — VC8 (2005), 9 — VC9, 10 — VC10 (2010), 11 — VC11 (2012).
gavLibFilesQtShared — имена .lib-файлов для динамически подключаемой библиотеки Qt;
gavLibFilesQtStatic — имена .lib-файлов для статически линкуемой библиотеки Qt.
gavLibFilesCrt — имена .lib-файлов для стандартных динамических библиотек, используемых в Windows.
iModeQt — режим линковки библиотеки Qt.
gavCompMode — флаги режима компиляции (однопоточные, многопоточные и т.п.).
gavOptimize — флаги оптимизации кода компилятором.
Чаще всего приходится менять параметры:
gavSrc — имена файлов с исходным кодом, разделённые пробелом (если их несколько).
bLibQt — флаг (0/1) необходимости использовать библиотеку Qt при сборке приложения.
bLibCrt — флаг (0/1) необходимости использовать стандартные CRT-библиотеки Windows при сборке приложения.
bLibBoost — флаг (0/1) необходимости использовать библиотеку Boost при сборке приложения.
gavSubsystem — подсистема создаваемого приложения: CONSOLE — консольное, WINDOWS — с графическим интерфейсом.
Результат (ошибки, сообщения) компиляции можно просмотреть в файле __vc++_XXX.log, где XXX — имя основного исходного файла
Сборка cpp-приложения из файлов проектов
Аналогично без запуска IDE можно собрать проект, используя файлы проектов и воркспейсов (dsp, dsw).
Код сценария vc++_dsp_dsw_compile.cmd
:: Перед использованием сценария рекомендуется задать системную переменную sVSPathName, :: указывающую путь к основному исполнимому файлу Visual Studio либо раскомментировать :: и отредактировать sVSPathName ниже в этом файле. @echo off cls echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- :: -------------------------------------- :: :: имя файла проекта (dsp) или вокспейса (dsw): set sPrjFile=MyWorkspace.dsp :: -------------------------------------- :: :: Режим компиляции: 0 - release, 1 - debug, 2 - release и debug: set iMode=2 :: -------------------------------------- :: :: Режим обработки файлов: :: 0 - удаление промежуточных файлов, :: 1 - перекомпиляция изменившихся фйлов, :: 2 - полная пересборка проекта (рекомендуется при iMode=2) set iSubMode=2 :: -------------------------------------- :: :: Имя конфигурации: if %sPrjFile:.dsp=% == %sPrjFile% ( set sPrjName=%sPrjFile:.dsw=% ) ELSE ( set sPrjName=%sPrjFile:.dsp=% ) :: Имя конфигурации - для режима release: set sConfigNameRelease="%sPrjName% - Win32 Release" :: Имя конфигурации - для режима debug: set sConfigNameDebug="%sPrjName% - Win32 Debug" :: -------------------------------------- :: :: пути к Visual Studio: :: set sVSPathName=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 6.0\Common\MSDev98\Bin\MSDEV.EXE :: set sVSPathName=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 8\Common7\IDE\VCExpress.exe :: set sVSPathName=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe :: -------------------------------------- :: :: Подрежим: if %iSubMode%==0 ( set iCompMode=/CLEAN ) if %iSubMode%==1 ( set iCompMode= ) if %iSubMode%==2 ( set iCompMode=/REBUILD ) :: -------------------------------------- :: echo. echo --------------------------------- echo [%sPrjName%]: compiling start. echo --------------------------------- echo. @echo off if %iMode%==0 ( :: режим release: echo [%sPrjName%]: configuration mode: echo %sConfigNameRelease% echo on "%sVSPathName%" %sPrjFile% /MAKE %sConfigNameRelease% %iCompMode% /OUT __vc++_compile_release.log ) @echo off if %iMode%==1 ( :: режим debug: echo [%sPrjName%]: configuration mode: echo %sConfigNameDebug% echo on "%sVSPathName%" %sPrjFile% /MAKE %sConfigNameDebug% %iCompMode% /OUT __vc++_compile_debug.log ) @echo off if %iMode%==2 ( :: режим release и debug: echo [%sPrjName%]: configuration modes: echo %sConfigNameRelease% echo %sConfigNameDebug% echo on "%sVSPathName%" %sPrjFile% /MAKE %sConfigNameRelease% %iCompMode% /OUT __vc++_compile_release.log "%sVSPathName%" %sPrjFile% /MAKE %sConfigNameDebug% %iCompMode% /OUT __vc++_compile_debug.log ) @echo off echo. echo --------------------------------- echo [%sPrjName%]: compiling end. echo --------------------------------- echo. echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- :: -------------------------------------- :: pause
Компиляция cs-файлов
Вышерассмотренный функционал реализуем и для C#:
Код сценария vc#_compile_and_link.cmd
:: --------------------------------------------------------------------------- :: :: Перед использованием сценария рекомендуется задать системные переменные: :: :: sVSPath - путь к корневому каталогу Visual C#, :: :: sVSPathName - путь к основному исполнимому файлу Visual C# :: :: (либо отредактировать sVSPath, sVSPathName ниже в файле. :: --------------------------------------------------------------------------- :: echo off cls echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- :: -------------------------------------- :: :: Имена исходников (через пробел) :: :: -------------------------------------- :: set gavSrc=Program.cs :: -------------------------------------- :: :: Режим компиляции: :: :: 0 - release, :: :: 1 - debug, :: :: -------------------------------------- :: set iModeComp=1 :: -------------------------------------- :: :: Подсистема приложения (одна из) :: :: -------------------------------------- :: :: /target:exe Построить консольный исполняемый файл (по умолчанию) (Краткая форма: /t:exe) set gavSubsystem=exe :: /target:winexe Построить исполняемый файл Windows (Краткая форма: /t:winexe) ::set gavSubsystem=winexe :: /target:library Построить библиотеку (Краткая форма: /t:library) ::set gavSubsystem=library :: /target:module Построение модуля, который может быть добавлен в другую сборку (Краткая форма: /t:module) ::set gavSubsystem=module :: /target:appcontainerexe Построение исполняемого файла Appcontainer (Краткая форма: /t:appcontainerexe) ::set gavSubsystem=appcontainerexe :: /target:winmdobj Построение промежуточного файла среды выполнения Windows, используемого WinMDExp (Краткая форма: /t:winmdobj) ::set gavSubsystem=winmdobj :: -------------------------------------- :: :: ПЛАТФОРМА приложения (одна из) :: :: (x86, Itanium, x64, arm или anycpu. :: :: Платформа по умолчанию: anycpu.) :: :: -------------------------------------- :: set gavPlatform=anycpu :: -------------------------------------- :: :: Дополнительные флаги компилятора :: :: -------------------------------------- :: ::set gavCompilFlags= :: -------------------------------------- :: :: Пути к Visual Studio. :: :: . без кавычек . :: :: -------------------------------------- :: set sVSPath=%WINDIR%\Microsoft.NET\Framework\v4.0.30319 set sVSPathName=%sVSPath%\csc.exe :: -------------------------------------- :: :: Настройка путей к подключаемым :: :: файлам. Каждый путь должен быть :: :: отдельной переменной ! :: :: -------------------------------------- :: set gavIncPathVS="%sVSPath%" if not "%gavIncPathMy%"=="" (set gavIncPathAll=-I"%gavIncPathMy%") if not %gavIncPathVS%=="" (set gavIncPathAll=%gavIncPathAll% -I%gavIncPathVS%) echo Include pathes: %gavIncPathAll% :: -------------------------------------- :: :: Настройка путей к библиотечным (.lib) :: :: файлам. Каждый путь должен быть :: :: отдельной переменной ! :: :: -------------------------------------- :: set gavLibPathVS=%sVSPath% if not "%gavLibPathVS%"=="" (set gavLibPathAll=/lib:"%gavLibPathVS%") if not "%gavLibPathMy%"=="" (set gavLibPathAll=%gavLibPathAll% /lib:"%gavLibPathMy%") echo Lib pathes: %gavLibPathAll% :: -------------------------------------- :: :: Файлы библиотеки run-time. :: :: При необходимости добавить сюда нужные :: :: -------------------------------------- :: :: set gavLibFilesCrt=user32.lib ole32.lib Gdi32.lib Ws2_32.lib Imm32.lib Comdlg32.lib Winspool.lib Advapi32.lib ::set gavLibFilesCrt="" if not "%gavLibFilesCrt%"=="" (set gavLibFilesAll=%gavLibFilesCrt%) echo Lib files: %gavLibFilesAll% :: -------------------------------------- :: :: Настройка режимов компиляции :: :: -------------------------------------- :: if %iModeComp%==0 ( set gavCompilFlags=%gavCompilFlags% /D:_RELEASE set gavCompMode=/debug- set gavOptimize=/optimize+ ) if %iModeComp%==1 ( set gavCompilFlags=%gavCompilFlags% /D:_DEBUG set gavCompMode=/debug+ set gavOptimize=/optimize- ) :: -------------------------------------- :: :: Настройка подсистемы приложения :: :: -------------------------------------- :: if not %gavSubsystem%=="" (set gavLinkSubsys=/t:%gavSubsystem%) :: -------------------------------------- :: set gavDelExt=*.obj, *.exe, *.log, *.pdb echo. echo Deleting old files: %gavDelExt% . echo. del %gavDelExt% echo. echo ------------------ echo Compiling start. echo ------------------ echo. echo on "%sVSPathName%" %gavDefine% %gavCompilFlags% %gavCompMode% %gavOptimize% %gavLinkSubsys% /utf8output /fullpaths /platform:%gavPlatform% %gavLibPathAll% %gavLibFilesAll% %gavSrc%>__vc#_compile.log @echo off echo. echo ------------------ echo Compiling end. echo ------------------ echo. echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- :: -------------------------------------- :: pause
Сборка cs-приложения из файлов солюшенов (sln) и проектов (csproj)
Код сценария vc#_sln_csproj_compile.cmd
:: Перед использованием сценария рекомендуется задать системную переменную sVSPathName, :: указывающую путь к основному исполнимому файлу Visual Studio либо раскомментировать :: и отредактировать sVSPathName ниже в этом файле. @echo off cls echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- :: -------------------------------------- :: :: имя файла проекта (.csproj) или вокспейса (sln): set sPrjFile=MyProject.csproj :: -------------------------------------- :: :: Режим компиляции: 0 - release, 1 - debug, 2 - release и debug: set iMode=2 :: -------------------------------------- :: :: Режим обработки файлов: :: 0 - удаление промежуточных файлов, :: 1 - перекомпиляция изменившихся фйлов, :: 2 - полная пересборка проекта (рекомендуется при iMode=2) set iSubMode=2 :: -------------------------------------- :: :: Имя конфигурации: if %sPrjFile:.sln=% == %sPrjFile% ( set sPrjName=%sPrjFile:.sln=% ) ELSE ( set sPrjName=%sPrjFile:.csproj=% ) :: Имя конфигурации - для режима release: :: set sConfigNameRelease="Release|Win32" set sConfigNameRelease="Release" :: Имя конфигурации - для режима debug: :: set sConfigNameDebug="Debug|Win32" set sConfigNameDebug="Debug" :: -------------------------------------- :: :: пути к Visual Studio: set sVSPathName=%SYSTEMDRIVE%\Program Files (x86)\Microsoft Visual Studio\11.0\Common7\IDE\devenv.exe :: set sVSPathName=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 8\Common7\IDE\VCExpress.exe :: set sVSPathName=%SYSTEMDRIVE%\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe :: -------------------------------------- :: :: Подрежим: if %iSubMode%==0 ( set iCompMode=/Clean ) if %iSubMode%==1 ( set iCompMode= ) if %iSubMode%==2 ( set iCompMode=/Rebuild ) :: -------------------------------------- :: echo. echo --------------------------------- echo [%sPrjName%]: compiling start. echo --------------------------------- echo. @echo off if %iMode%==0 ( :: режим release: echo [%sPrjName%]: configuration mode: echo %sConfigNameRelease% echo on "%sVSPathName%" %sPrjFile% /Build %sConfigNameRelease% /Out __vc#_compile_release.log ) @echo off if %iMode%==1 ( :: режим debug: echo [%sPrjName%]: configuration mode: echo %sConfigNameDebug% echo on "%sVSPathName%" %sPrjFile% /Build %sConfigNameDebug% /Out __vc#_compile_debug.log ) @echo off if %iMode%==2 ( :: режим release и debug: echo [%sPrjName%]: configuration modes: echo %sConfigNameRelease% echo %sConfigNameDebug% echo on "%sVSPathName%" %sPrjFile% /Build %sConfigNameRelease% /Out __vc#_compile_release.log "%sVSPathName%" %sPrjFile% /Build %sConfigNameDebug% /Out __vc#_compile_debug.log Rem /project lxDbLib.csproj /projectconfig Debug ) @echo off echo. echo --------------------------------- echo [%sPrjName%]: compiling end. echo --------------------------------- echo. echo -------------------------------------- echo ------ %date% [%time%] ------ echo -------------------------------------- echo ---------- . -=LEXX=- . ---------- echo -------------------------------------- :: -------------------------------------- :: pause
На первый взгляд громоздкость данного кода, компенсируется простотой последующей работы в консоли. Всем приятного программирования.
Компилятор Visual Studio (начало работы)
Цель данной статьи осветить некоторые тонкие моменты компиляции c++ приложения компилятором Visual Studio. Все примеры будут компилироваться из командной строки (bat файлами) это позволит лучше понять происходящее. В примерах я использую Visual Studio Express 2012 for Windows Desktop.
Рассмотрим следующий простой пример консольного приложения Windows в котором печатаются все параметры, передаваемые через командную строку, и переменные окружения (envp — это указатель на массив, содержащий переменные окружения с их значениями, разделенные знаком равенства (=)):
#include #include int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) < _tprintf(TEXT("argc = %d\n"), argc); for(int i = 0; i < argc; ++i) < _tprintf(TEXT("argv[%d] = \"%s\"\n"), i, argv[i]); >int n = 0; while(envp[n] != NULL) < _tprintf(TEXT("envp[%d] = \"%s\"\n"), n, envp[n]); n++; >return 0; >
.bat файл, компилирующий этот пример, имеет вид:
set "vc_path=C:\Program Files\Microsoft Visual Studio 11.0\VC\" call "%vc_path%vcvarsall.bat" x86 set "bin=bin\" set "src=src\" set "progname=simple" "%vc_path%bin\cl.exe" /c /ZI /nologo /W3 /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" ^ /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"%bin%%progname%.obj" ^ /Fd"%bin%%progname%.pdb" /Gd /TP /analyze- /errorReport:prompt %src%%progname%.cpp "%vc_path%bin\link.exe" /ERRORREPORT:PROMPT /OUT:"%bin%%progname%.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib ^ gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ^ odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" ^ /manifest:embed /DEBUG /PDB:"%bin%%progname%.pdb" /TLBID:1 /DYNAMICBASE /NXCOMPAT ^ /IMPLIB:"%bin%%progname%.lib" /MACHINE:X86 %bin%%progname%.obj pause
При этом предполагается следующее расположение файлов
Во всех Windows-приложениях должна быть входная функция, за реализацию которой отвечаете вы. Существует две такие функции:
int WINAPI _tWinMain( HINSTANCE hInstanceExe, HINSTANCE, PTSTR pszCmdLine, int nCmdShow); int _tmain( int argc, TCHAR *argv[], TCHAR *envp[]);
_tWinMain и _tmain это в действительности макросы, которые раскрываются как WinMain или wWinMain для _tWinMain и main или wmain для _tmain в зависимости от того используется Unicode или нет.
На самом деле входная функция операционной системой не вызывается. Вместо этого происходит обращение к стартовой функции из библиотеки C/C++, заданной во время компоновки параметром -entry: командной строки. Она инициализирует библиотеку С/С++, чтобы можно было вызывать такие функции, как malloc и free, а также обеспечивает корректное создание любых объявленных вами глобальных и статических С++-объектов до того, как начинается выполнение вашего кода. В следующей таблице показано, в каких случаях реализуются те или иные входные функции.
Типы приложений и соответствующие им входные функции
| Тип приложения | Входная функция | Стартовая функция, встраиваемая в исполняемый файл |
| GUI-приложение, работающее с ANSI-символами и строками | _tWinMain (WinMain) | WinMainCRTStartup |
| GUI-приложение, работающее с Unicode-символами и строками | _tWinMain (wWinMain) | wWinMainCRTStartup |
| CUI-приложение, работающее с ANSI-символами и строками | _tmain (main) | mainCRTStartup |
| CUI-приложение, работающее с Unicode-символами и строками | _tmain (wmain) | wmainCRTStartup |
Компоновщик отвечает за выбор подходящей стартовой функции из библиотеки С/С++ при компоновке исполняемого файла. Если задан ключ /SUBSYSTEM:WINDOWS, компоновщик ищет в коде функцию WinMain или wWinMain. Если этих функций нет, компоновщик сообщает об ошибке «unresolved external symbol». В противном случае компоновщик выбирает WinMainCRTStartup или wWinMainCRTStartup, соответственно.
Аналогичным образом, если задан ключ /SUBSYSTEM:CONSOLE, компоновщик ищет в коде функцию main или wmain и выбирает соответственно mainCRTStartup или wmainCRTStartup; если в коде нет ни main, ни wmain, сообщается о той же ошибке – «unresolved external symbol».
Но не многие знают, что в проекте можно вообще не указывать ключ /SUBSYSTEM компоновщика. Если вы так и сделаете, компоновщик будет сам определять подсистему для вашего приложения. При компоновке он проверит, какая из четырех функций ( WinMain, wWinMain, main или wmain ) присутствует в вашем коде, и на основании этого выбирет подсистему и стартовую функцию из библиотеки С/С++.
Теперь несколько замечаний по .bat файлу и ключам компилятора и компоновщика
При создании .bat файла нужно четко следить за тем, чтобы создаваемый текстовый файл имел формат завершения строки в стиле Windows или Unix, но не Mac, иначе bat файл просто не будет запускаться.
Для нормальной работы компилятора перед вызовом cl.exe или link.exe необходимо вызвать call “%vc_path%vcvarsall.bat” x86. Этот bat файл инициализирует переменные окружения INCLUDE, LIB, LIBPATH, PATH и некоторые другие необходимые для работы cl.exe и link.exe. Например, в моем случае было
set "INCLUDE=C:\Program Files\Microsoft Visual Studio 11.0\VC\INCLUDE;C:\Program Files\Windows Kits\8.0\include\shared;C:\Program Files\Windows Kits\8.0\include\um;C:\Program Files\Windows Kits\8.0\include\winrt;" set "LIB=C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;C:\Program Files\Windows Kits\8.0\lib\win8\um\x86;" set "LIBPATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;C:\Program Files\Windows Kits\8.0\References\CommonConfiguration\Neutral;C:\Program Files\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.VCLibs\11.0\References\CommonConfiguration\neutral;"
При вызове cl.exe использовались следующие ключи:
- /с – компиляция без связывания
- /ZI – компилятор включает отладочную информацию в базу данных приложения (только для x86)
- /nologo – подавляет отображение информации о компиляторе
- /W3 – устанавливает уровень предупреждений компилятора на 3 уровень
- /Od – отключает оптимизацию (так как /Od предотвращает перемещение кода, установка этого ключа облегчает процесс отладки)
- /Oy – предотвращает создание указателей фрейма в стеке вызова, /Oy- отключает такое поведение (только для x86)
- /D “_DEBUG” – определяется при компиляции с ключами /LDd, /MDd и /MTd
- /D “_WINDOWS” – определяет, что целевая OS – Windows
- /D “UNICODE” – указывает компилятору на необходимость использовать в приложении версии Win API функций для работы с Unicode
Например, вот фрагмент из WinUser.h:
#ifdef UNICODE #define CreateWindowEx CreateWindowExW #else #define CreateWindowEx CreateWindowExA #endif
#ifdef _UNICODE #define _tcslen wcslen #else #define _tcslen strlen #endif
- инициализацию локальных переменных ненулевыми значениями. Это позволяет идентифицировать баги, которые не проявляются в отладочной сборке. Больщая вероятность, что переменная в стеке будет оставаться нулевой в отладочной сборке нежели в рилизной сборке, так как компилятор оптимизирует стек переменных в рилиной сборке. Будучи однажды использованной память отведенная под стек не обнуляется компилятором. По этому, последующие не инициализированные переменные в стеке будут содержать значения оставшееся от предыдущего использования этой области памяти.
- Проверка выхода за границы локальных переменных, таких как массивы. /RTCs не определяет выход за границы при обращении к памяти явившейся результатом выравнивания компилятором положения структуры в памяти. Такое может произойти при использовании выравнивания (С++ ), /Zp или pack или, если вы распологаете элементы структуры в таком порядке, который вынуждает компилятор вставлять отступы.
- Проверка указателя стека, что позволяет определить разрушение указателя стека. Разрушение указателя стека может произойти при несоответствии типов вызова. Например, используя указатель на функцию, вы можите вызвать функцию из DLL, которая экспортируется как __stdcall, но вы определили указатель на функцию как __cdecl.
Замечание:
стековый фрейм (функции) – область памяти, выделяемая всякий раз, когда вызывается функция, предназначается для временного хранения аргументов и локальных переменных функции.
/RTCu – заставляет компилятор выдавать предупреждения, когда переменная используется без инициализации. Например, команда, которая генерирует предупреждение (4-го уровня) С4701 может также генерировать ошибку времени выполнения при установленном ключе /RTCu. Любые команды, которые генерируют предупреждения компилятора (уровня 1 и 4) С4700, будут также генерировать ошибку времени выполнения при установленном ключе /RTCu.
Тем не менее, рассмотрим следующий фрагмент кода:
int a, *b, c; if ( 1 ) < b = &a; >c = a; // No run-time error with /RTCu
Если переменная могла быть проинициализирована, установка ключа /RTCu не приведет к предупреждению времени исполнения. В сущности, вы можете проинициализировать переменную, выполняя операцию взятия ее адреса. В последнем фрагменте кода оператор & работает как оператор присваивания. (. )
Какой компилятор в visual studio
Всем здравствуйте!
Небольшое вступление: я новичок в программировании, но к каждому совету и мнению я прислушиваюсь. Я отношусь с уважением ко всем людям в целом и прошу такого же отношения и ко мне. Если я где-то ошибаюсь — прошу меня поправить, а не писать сообщения с негативным содержанием.
Теперь по сути. Я решил начать свое знакомство с C++, используя Microsoft Visual Studio. И у меня возникли некоторые вопросы касательно выбора версии\других программ.
Первый момент: это отличия Visual C+ от других программ. Насколько я понял, Visual Studio — это набор инструментов, включающий в себя и графический интерфейс, и компилятор, и отладчик. Скажи, чем он отличается от других сред разработки\программ?
Второй момент: это выбор версии. Не могу выбрать из 2х версий: 2013 и 2015 года. Кто пользуется какой — поделитесь опытом, расскажите, какая лучше и чем отличаются.
Вот в общем и все мои вопросы. Если я написал тему не в том разделе: то простите, я тему пересоздам. Правила форума я прочитал и не нарушал их. Всем заранее спасибо!
Вредный кошак
Участник клуба
Регистрация: 14.10.2012
Сообщений: 1,159
| Всем здравствуйте! |
Приветствую.
Выражу своё, никому не нужное мнение.
На единственно верное мнение оно не претендует
| Я отношусь с уважением ко всем людям в целом и прошу такого же отношения и ко мне. |
Ой, как Вы к нам, так и мы к Вам. Всё честно.
| Первый момент: это отличия Visual C+ от других программ. Насколько я понял, Visual Studio — это набор инструментов, включающий в себя и графический интерфейс, и компилятор, и отладчик. Скажи, чем он отличается от других сред разработки\программ? |
Фактически, это такая же программа, как и все остальные.
Чем один офисный пакет отличается от другого?
Правильно — инструментарием, внешним видом, возможностями, лицензией и т.д.
У студии запоздалая поддержка новых стандартов,
плюс не везде оно соответствует стандарту языка C++.
Берите студию, которая поновее.
Думаю, для обучения хватит бесплатной версии.
Что касается кто какой пользуется,
то последняя, которой я пользовался — 2012.
Предпочитаю другие IDE и компилятор.
Ну и да, окошки я давно поменял на пингвинов.
| Я решил начать свое знакомство с C++ |
А раньше программировали?
Просто C++ — очень сложный, мощный, обширный язык,
с кучей граблей, тонкостей, и других «прекрасных» вещей.
Для освоения с нуля может быть просто неподъемным.
| Вот в общем и все мои вопросы. |
Ну, если что, задавайте еще.
Могу многое рассказать о C++
Ну и по смежным темам тоже.
Последний раз редактировалось Croessmah; 27.06.2016 в 20:44 .
Регистрация: 12.01.2011
Сообщений: 19,500
VS это IDE. Грубо говоря компилятор (С++) + редактор кода, ну и всякие фишки типа автодополнения при вводе, подсветки, рефакторинга. Отладчика, профайлера.
Если использовать в коде только то, что есть в стандарте С++ (С++98, С++11, С++14, . ), то код обычно будет можно компилировать и другими компиляторами (GCC/MinGW, . ) поддерживающими стандарт.
Еще есть платформо-зависимые вещи типа WinAPI на винде.
Про графический интерфейс непонятно что вы имеете в виду. Если про создание программ с GUI, то в мире С++ (в отличии от например Дельфи) нет стандартной GUI библиотеки, есть куча разных GUI библиотек например Qt, GTK, MFC, VCL (C++ Builder), wxWidgets, .
В студии по умолчанию есть MFC, но наверно это не самый простой и удобный выбор для начала.
В Qt документация хорошая, так что советую на него посмотреть.
Qt можно и в Студии, у них даже есть add-in для некоторой интеграции и облеглечения работы (открытие Qt Designer для .ui файлов например), но наверно проще будет в IDE Qt Creator.
(еще в Visual Studio есть C++/CLI WinForms, но это не чистый С++, а .NET, и нет никакого смысла его использовать в С++ кроме специфичных задач типа связывания .NET и С++ кода; если хотите .NET, то намного проще взять C#)
А про версию студии, естественно лучше самую новую если нет необходимости в более старой (для старых проектов работающих на ней и т.п.)
В 2015 еще есть бесплатное Community издание (аналог Про), а не только Express.
| У студии запоздалая поддержка новых стандартов, плюс не везде оно соответствует стандарту языка C++. |
В последних версиях это вроде уже не сильно актуально.
Последний раз редактировалось Alex11223; 27.06.2016 в 20:49 .
Где 64-битный компилятор в Visual Studio?
Часто можно встретить вопросы, которые связаны с тем, что не удается создать 64-битную конфигурацию проекта в Visual Studio или скомпилировать уже имеющийся 64-битный проект. Практически всегда это связано с отсутствием установленного 64-битного компилятора.
Причин отсутствия 64-битного компилятора две:
- Используется версия Visual Studio Express, в которой отсутствует 64-битный компилятор. В этом случае необходимо приобрести соответствующую редакцию Visual Studio.
- При установке Visual Studio 2005/2008 по умолчанию установка 64-битного компилятора отключена (рисунок 1). Высока вероятность, что при установке вы не установили галочку «X64 Compilers and Tools». В этом случае запустите инсталлятор и установите недостающие компоненты.

Рисунок 1 — При установке не выбран 64-битный компилятор
Библиографический список
- Андрей Карпов. 7 шагов по переносу программы на 64-битную систему.
- Уроки разработки 64-битных приложений на языке Си/Си++.
