일반적으로 프로젝트 빌드시 프로젝트에 포함된 모든 소스 파일들이 컴파일된다.
때문에 소스가 커지면 자연적으로 전체 프로젝트 빌드 시간이 늘어나는 단점이 있다.
Visual C++ 에서는 PCH(PreCompliedHeader) 라는 기능을 제공하고 있다.
pch 는 자주 변경되지 않은 헤더(cpp 포함)를 미리 한번만 컴파일 해놓으면 다음 빌드부터는 수정된 부분만 컴파일되어 전체 빌드 시간을 줄일 수 있다.
기본적으로 Visual C++ 프로젝트 생성시 Wizard 를 이용하게 되면 Stdafx.h 파일이 추가된다.
그리고 Stdafx.h 파일을 각각의 .cpp 파일에서 인클루드하였으면 pch 를 사용할 수 있다.
[pch 설정하기]
프로젝트속성 -> C/C++ -> 미리 컴파일된 헤더
미리 컴파일된 헤더 -> 사용(/Yu)
미리 컴파일된 헤더 파일 -> StdAfx.h
미리 컴파일된 헤더 출력 파일 -> $(IntDir)$(TargetName).pch
위와 같이 설정하면 후 재빌드하면 프로젝트명.pch 이 생성된다.
만약 pch 사용 설정을 했는데도 전체 소스를 컴파일 하면 재빌드를 수행하여 pch 파일을 다시 생성하도록 한다.
참고 https://msdn.microsoft.com/ko-kr/library/h552b3ca.aspx
hiredis for windows
hiredis windows 구글링을 하면 윈도우용으로 포팅된것을 사용할 수 있다고 나온다.
MS OpenTech
공식웹 https://msopentech.com
프로젝트 https://github.com/MSOpenTech
에서는 다양한 오픈소스를 윈도우용으로 포팅하여 제공해주고 있다.
redis 는 공식적으로 리눅스만 지원하지만 MSOpenTech 에서 윈도우용으로 포팅된 Redis 를 제공한다. Redis 프로젝트내에 hiredis 가 있는데 이것을 사용하기 위함이다.
# 윈도우용 redis 다운 받기
git clone https://github.com/MSOpenTech/Redis
# hiredis library 빌드 하기
msvs\RedisServer.sln 실행
hiredis -> 속성 -> 구성 -> 일반 -> 플랫폼 도구 집합 -> visual studio 버전 선택 후 빌드
# vs2012 이전 버전에서는 'winapifamily.h' 에러가 발생하여
C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ 경로 추가
# hiredis 자체는 lib 빌드는 잘 된다.
msvs\x64\Debug\hiredis.lib
msvs\x64\Release\hiredis.lib
# 하지만 프로젝트에 hiredis.lib 사용하려면 문제가 발생한다.
# 우선 소스 경로 추가
src\
deps\hiredis
# vs2010 의 경우 우선 'winapifamily.h' 에러가 발생한다.
# C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ 경로 추가하면 이부분은 해결된다.
오류 1 error C1083: 포함 파일을 열 수 없습니다. 'winapifamily.h': No such file or directory c:\users\ysoftman\downloads\redis-win-2.8.17.3\src\win32_interop\WS2tcpip.h 51
MS OpenTech
공식웹 https://msopentech.com
프로젝트 https://github.com/MSOpenTech
에서는 다양한 오픈소스를 윈도우용으로 포팅하여 제공해주고 있다.
redis 는 공식적으로 리눅스만 지원하지만 MSOpenTech 에서 윈도우용으로 포팅된 Redis 를 제공한다. Redis 프로젝트내에 hiredis 가 있는데 이것을 사용하기 위함이다.
# 윈도우용 redis 다운 받기
git clone https://github.com/MSOpenTech/Redis
# hiredis library 빌드 하기
msvs\RedisServer.sln 실행
hiredis -> 속성 -> 구성 -> 일반 -> 플랫폼 도구 집합 -> visual studio 버전 선택 후 빌드
# vs2012 이전 버전에서는 'winapifamily.h' 에러가 발생하여
C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ 경로 추가
# hiredis 자체는 lib 빌드는 잘 된다.
msvs\x64\Debug\hiredis.lib
msvs\x64\Release\hiredis.lib
# 하지만 프로젝트에 hiredis.lib 사용하려면 문제가 발생한다.
# 우선 소스 경로 추가
src\
deps\hiredis
# vs2010 의 경우 우선 'winapifamily.h' 에러가 발생한다.
# C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ 경로 추가하면 이부분은 해결된다.
오류 1 error C1083: 포함 파일을 열 수 없습니다. 'winapifamily.h': No such file or directory c:\users\ysoftman\downloads\redis-win-2.8.17.3\src\win32_interop\WS2tcpip.h 51
# vs2010, vs2012 모두 매크로 중복 정의 에러가 발생한다.
오류 1 error C4005: 'ECONNRESET' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 100
오류 2 error C4005: 'EINPROGRESS' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 104
오류 3 error C4005: 'ETIMEDOUT' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 130
오류 1 error C4005: 'ECONNRESET' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 100
오류 2 error C4005: 'EINPROGRESS' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 104
오류 3 error C4005: 'ETIMEDOUT' : 매크로 재정의 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\errno.h 130
결론적으로 MSOpenTehc 에서 제공하는 hiredis 윈도우용으로 사용 실패다.
최신 버전을 바로 사용할 수도 없고 vs 버전별 설정해야할 것도 다른것을 봤을때 MSOpenTech hiredis windows 빌드는 왠만하면 쓰지 않는 것이 정신건강에 좋을 것 같다.ㅠ
대신 hiredis 자체를 VS 프로젝트로 포팅한 것을 발견했다.
https://github.com/texnician/hiredis-win32
대신 hiredis 자체를 VS 프로젝트로 포팅한 것을 발견했다.
https://github.com/texnician/hiredis-win32
import unity3d to visual studio
유니티(Unity3D)의 Monodevelop 는 VisualStudio(VS) 에 비하면 꽤 불편한다.
익숙한 VS 로 유니티 개발을 하기위해선 Visual Studio Tools for Unity 을 사용하면 된다.
VS 버전에 맞게 다운로드 받아 설치하자.
(MS 가 SyntaxTree 를 인수하면서 무료로 제공된다.)
http://unityvs.com/
이제 유니티를 실행(또는 재실행)하여
Assets메뉴 -> Import Package -> Visual Studio 2012 Tools 로 임포트한다.
이제 유니티에서 Visual Studio Tools 메뉴가 생겼다.
Visual Studio Tools -> Open in Visual Studio 로 사용할 수 있다.
(콘솔 메시지를 더블클릭해도 VS 로 처리된다.)
익숙한 VS 로 유니티 개발을 하기위해선 Visual Studio Tools for Unity 을 사용하면 된다.
VS 버전에 맞게 다운로드 받아 설치하자.
(MS 가 SyntaxTree 를 인수하면서 무료로 제공된다.)
http://unityvs.com/
이제 유니티를 실행(또는 재실행)하여
Assets메뉴 -> Import Package -> Visual Studio 2012 Tools 로 임포트한다.
이제 유니티에서 Visual Studio Tools 메뉴가 생겼다.
Visual Studio Tools -> Open in Visual Studio 로 사용할 수 있다.
(콘솔 메시지를 더블클릭해도 VS 로 처리된다.)
Visual C++ Command Line Build
Visual C++ 를 Jenkins이나 Hudson 같은 CI 환경이나 기타 커맨드 라인에서 빌드해야 할 때가 있다.
이럴 때는 deven.exe 를 사용하자.
devenv.exe 실행 파일은 Visual Stdudio IDE 를 실행시키지만 /Build 옵션으로 IDE를 열지 않고 커맨드라인에서 빌드할 수 있다.
빌드 스크립트나 .bat 에 작성하여 사용하자.
(커맨드 프롬프트에서 명령을 실행하면 별도의 프로세스로 실행되어 순차 진행에는 적합하지 않다.)
예) .bat 작성
@rem devenv.exe -> GUI 모드
@rem devenv.com -> console 모드
@rem 빌드 결과물 삭제
"c:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.com" ysoftman.sln /clean "debug|x64"
@rem ysoftman.sln 빌드하기(빌드로그는 .log 로 출력디렉토리에 자동 생성된다.)
@rem /log 옵션 사용시 ide 동작이 로깅되며 기본 저장은 %APPDATA%\Microsoft\VisualStudio\버전\ActivityLog.xml 이 된다.
@rem 현재 위치에 로그를 출력하려면 다음과 같이 로그경로를 지정한다.
빌드 스크립트나 .bat 에 작성하여 사용하자.
(커맨드 프롬프트에서 명령을 실행하면 별도의 프로세스로 실행되어 순차 진행에는 적합하지 않다.)
예) .bat 작성
@rem devenv.exe -> GUI 모드
@rem devenv.com -> console 모드
@rem 빌드 결과물 삭제
"c:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.com" ysoftman.sln /clean "debug|x64"
@rem ysoftman.sln 빌드하기(빌드로그는 .log 로 출력디렉토리에 자동 생성된다.)
@rem /log 옵션 사용시 ide 동작이 로깅되며 기본 저장은 %APPDATA%\Microsoft\VisualStudio\버전\ActivityLog.xml 이 된다.
@rem 현재 위치에 로그를 출력하려면 다음과 같이 로그경로를 지정한다.
"c:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.com" ysoftman.sln /build "debug|x64" /log "%cd%\ActivityLog_IDE.xml"
참고로 /? 옵션으로 자세한 사용방법을 확인 할 수 있다.
"c:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe" /?
Visual C++ build optimization
크래시 덤프 파일을 열어 보면 값이 물음표(?)나 나올 수 없는 값들이 나온다면, 최적화 사용 안함(/Od)으로 빌드 해보자.
Release 모드의 디폴트 최적화 옵션은 속도 최대화(/O2)로 설정되어 있다.
최적화 옵션 자세한 설명 http://msdn.microsoft.com/ko-kr/library/8f8h5cxt.aspx
C Coding Convention and Naming Notation
# BSD Convention(style)
# 버클리 대학교 Eric Allman 프로그램머의 이름을 따 Allman 스타일이라고도 한다.
# 함수와 조건문 반복문 모두 중괄호 시작 위치가 뉴라인에서 시작한다.
# 장점: 중괄호의 시작 위치가 일관적이라 코드 읽기가 쉽다.
# 단점: 라인 수 증가
int funcA()
{
if (condition > 0)
{
result = 1 + 1;
}
}
# K&R(Kernighan and Ritchie) Convention(style)
# C 언어를 만드신 두분의 이름을 딴 스타일로
# 함수에는 BSD 와 같이 중괄호 시작위치가 뉴라인에서 시작하지만
# 조건문과 반복문에서는 공백후 시작한다.
# 장점: 코드량(라인수) 감소
# 단점: 중괄호 시작 위치에 일관성이 없어 BSD 에 비해 코드 읽기가 어렵다.
int funcA()
{
if (condition > 0) {
result = 1 + 1;
}
}
# 참고로 함수 이름 과 { 시작 전에 파라미터를 선언하는 것으로
# K&R(Kernighan and Ritchie) old(obsolete)스타일로 거의 사용하지 않는다.
int func1(int_param, char_param)
int int_param;
char *char_param;
{
printf("%s int_param=%d char_param=%s\n", __FUNCTION__, int_param, char_param);
return 0;
}
# 기타 스타일
https://en.wikipedia.org/wiki/Indentation_style
# 헝가리언 표기법
# MS 프로그래머인 Charles Simonyi 가 사용한 이름 표기 방식으로 특수한 prefix 를 사용한다.
bool bFlag;
char *pName;
char cChar;
char szName[10];
int nIndex;
float fNum;
class CClass
# 카멜(Camel) 표기법
# 소문자로 시작해서 단어 사이를 대소문자로 구별한다.
void myTestFunction() {}
# 파스칼(Pascal) 표기법
# 첫번째 문자를 대문자로 시작한다.
void MyTestFunction() {}
# 버클리 대학교 Eric Allman 프로그램머의 이름을 따 Allman 스타일이라고도 한다.
# 함수와 조건문 반복문 모두 중괄호 시작 위치가 뉴라인에서 시작한다.
# 장점: 중괄호의 시작 위치가 일관적이라 코드 읽기가 쉽다.
# 단점: 라인 수 증가
int funcA()
{
if (condition > 0)
{
result = 1 + 1;
}
}
# K&R(Kernighan and Ritchie) Convention(style)
# C 언어를 만드신 두분의 이름을 딴 스타일로
# 함수에는 BSD 와 같이 중괄호 시작위치가 뉴라인에서 시작하지만
# 조건문과 반복문에서는 공백후 시작한다.
# 장점: 코드량(라인수) 감소
# 단점: 중괄호 시작 위치에 일관성이 없어 BSD 에 비해 코드 읽기가 어렵다.
int funcA()
{
if (condition > 0) {
result = 1 + 1;
}
}
# 참고로 함수 이름 과 { 시작 전에 파라미터를 선언하는 것으로
# K&R(Kernighan and Ritchie) old(obsolete)스타일로 거의 사용하지 않는다.
int func1(int_param, char_param)
int int_param;
char *char_param;
{
printf("%s int_param=%d char_param=%s\n", __FUNCTION__, int_param, char_param);
return 0;
}
# 기타 스타일
https://en.wikipedia.org/wiki/Indentation_style
# 헝가리언 표기법
# MS 프로그래머인 Charles Simonyi 가 사용한 이름 표기 방식으로 특수한 prefix 를 사용한다.
bool bFlag;
char *pName;
char cChar;
char szName[10];
int nIndex;
float fNum;
class CClass
# 카멜(Camel) 표기법
# 소문자로 시작해서 단어 사이를 대소문자로 구별한다.
void myTestFunction() {}
# 파스칼(Pascal) 표기법
# 첫번째 문자를 대문자로 시작한다.
void MyTestFunction() {}
Visual C++ 다시빌드 또는 빌드정리시 참조 라이브러리 파일이 삭제되는 현상
Visual C++ 솔루션이 다음과 같이 구성될때
TestA.vcxporj (빌드 출력 libTestA.lib)
TestB.vcxproj (libTestA.lib 를 사용, 빌드 출력 TestB.exe)
TestB 다시 빌드(또는 정리) 하면 원래는 libTestA.lib 은 삭제하지 말고 TestB.exe 와 관련된 중간 파일들만 삭제되어야 한다.
하지만 libTestA.lib 파일을 삭제하고 libTestA.lib 를 찾을 수 없다는 에러가 발생하는 경우가 있다.
이와 같은 현상이 발생하는 이유는 TestA 와 TestB 같은 중간 출력 디렉토리를 사용하고 있어서다.
VS2012 기준
속성 페이지 -> 구성속성 -> 일반 -> 중간 디렉토리 -> $(ProjectName)\$(Platform)\$(Configuration)\
로 각각의 독립된 프로젝트 디렉토리를 설정하면 해결된다.
[참고]
VS 가 프로젝트 빌드 정리시 중간 디렉토리의 *.tlog(TrackFileLog)를 참고해서 파일들을 삭제하는데, 다음과 같이 .vcxproj 에 설정하면 빌드시 .tlog 파일을 생성하지 않게 할 수 있다.
<PropertyGroup>
<TrackFileAccess>false</TrackFileAccess>
TestA.vcxporj (빌드 출력 libTestA.lib)
TestB.vcxproj (libTestA.lib 를 사용, 빌드 출력 TestB.exe)
TestB 다시 빌드(또는 정리) 하면 원래는 libTestA.lib 은 삭제하지 말고 TestB.exe 와 관련된 중간 파일들만 삭제되어야 한다.
하지만 libTestA.lib 파일을 삭제하고 libTestA.lib 를 찾을 수 없다는 에러가 발생하는 경우가 있다.
이와 같은 현상이 발생하는 이유는 TestA 와 TestB 같은 중간 출력 디렉토리를 사용하고 있어서다.
VS2012 기준
속성 페이지 -> 구성속성 -> 일반 -> 중간 디렉토리 -> $(ProjectName)\$(Platform)\$(Configuration)\
로 각각의 독립된 프로젝트 디렉토리를 설정하면 해결된다.
[참고]
VS 가 프로젝트 빌드 정리시 중간 디렉토리의 *.tlog(TrackFileLog)를 참고해서 파일들을 삭제하는데, 다음과 같이 .vcxproj 에 설정하면 빌드시 .tlog 파일을 생성하지 않게 할 수 있다.
<PropertyGroup>
<TrackFileAccess>false</TrackFileAccess>
</PropertyGroup>
이 방법은 어쩔 수 없이 두 프로젝트의 중간 디렉토리를 같게 하였을 경우만 사용하도록 하자.
Visual C++ C1010: 에러 해결방법
빌드시 다음과 같은 에러 발생시
방법1. 미리 컴파일된 헤더 사용안하기
프로젝트 속성 페이지 -> 구성 속성 -> 미리 컴파일된 헤더 -> 미리 컴파일된 헤더 -> 사용안함
방법2. 설정을 변경하지 않고 사용할때
#include "StdAfx.h" 를 에러가 발생한 소스(.cpp)에서 첫번째에 명시한다.
Visual C++ vcredist(재배포패키지) 버전 설정
Visual C++ 2008 도 세부적으론 다음과 같은 여러 버전이 존재한다.
RTM 버전은 9.0.21022.8
SP1 버전은 9.0.30729.1
SP1b(보안패치) 버전은 9.0.30729.4148
빌드 후 출력된 manifest 파일을 보면 위 버전 중 2개 이상을 링크하여 불필요하게 다수의 라이브러리(dll) 를 사용하는 경우가 발생할 수 있다.
RTM 버전은 9.0.21022.8
SP1 버전은 9.0.30729.1
SP1b(보안패치) 버전은 9.0.30729.4148
빌드 후 출력된 manifest 파일을 보면 위 버전 중 2개 이상을 링크하여 불필요하게 다수의 라이브러리(dll) 를 사용하는 경우가 발생할 수 있다.
manifest 는
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crtassem.h
를 참고하여 생성되는데 다음 매크로 정의에 따라 버전을 하나로 통일 시킬 수 있다.
#define _BIND_TO_CURRENT_VCLIBS_VERSION 0; // 기본 버전 사용
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1; // 최신 버전 사용
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crtassem.h
를 참고하여 생성되는데 다음 매크로 정의에 따라 버전을 하나로 통일 시킬 수 있다.
#define _BIND_TO_CURRENT_VCLIBS_VERSION 0; // 기본 버전 사용
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1; // 최신 버전 사용
debugging in Visual C++ 2008 Release
Release 모드에서 디버깅하려면 다음과 같이 설정한다.
프로젝트 속성 -> 구성속성 -> C/C++ -> 일반 -> 디버깅 정보 형식 -> 프로그램 데이터베이스(/Zi)
프로젝트 속성 -> 구성속성 -> C/C++ -> 최적화 -> 최적화 -> 사용안함(/Od)
프로젝트 속성 -> 구성속성 -> 링커 -> 디버깅 -> 디버그 정보 생성 -> 예(/DEBUG)
프로젝트 속성 -> 구성속성 -> C/C++ -> 일반 -> 디버깅 정보 형식 -> 프로그램 데이터베이스(/Zi)
프로젝트 속성 -> 구성속성 -> C/C++ -> 최적화 -> 최적화 -> 사용안함(/Od)
프로젝트 속성 -> 구성속성 -> 링커 -> 디버깅 -> 디버그 정보 생성 -> 예(/DEBUG)
C++ 헤더파일(.h) 중복 include 방지 방법 장단점
# 헤더파일(.h)이 중복 포함되어 불필요한 컴파일 시간이 늘어나는 것을 막기 위해 2가지 중복 포함 방지 방법이 있다.
# 첫번째 .h 중복 포함 방지
# 컴파일러에 따라 지원(Visual C++ 5.0 이상)안될 수 있지만 간결하게 사용할 수 있다.
#pragma once
# 두번째 .h 중복 포함 방지
# 코딩 줄 수가 첫번째 방법보다 많지만 표준이기 때문에 컴파일러에서 상관없이 사용할 수 있다.
#ifndef __YSOFTMAN_H__
#define __YSOFTMAN_H__
...
#endif
# 첫번째 .h 중복 포함 방지
# 컴파일러에 따라 지원(Visual C++ 5.0 이상)안될 수 있지만 간결하게 사용할 수 있다.
#pragma once
# 두번째 .h 중복 포함 방지
# 코딩 줄 수가 첫번째 방법보다 많지만 표준이기 때문에 컴파일러에서 상관없이 사용할 수 있다.
#ifndef __YSOFTMAN_H__
#define __YSOFTMAN_H__
...
#endif
Visual C++ 2012 실행마다 빌드 새로하는 현상 해결하기
Visual C++ 2012 사용시 모든 프로젝트를 빌드하였지만 디버깅(F5)/일반실행(Ctrl+F5)를 할때마나 전체 프로젝틀 다시 빌드하는 경우가 생긴다.
이것은 다른 프로젝트에 종속성 때문에 생기는 것으로 보통 해결 방법으로 프로젝트 종속성 팝업 메뉴에서 종속 프로젝트를 해제하려 하지만 "이 종속성은 프로젝트 시스템에서 추가했으며 제거할 수 없습니다" 라는 에러창이 뜨면서 종속성을 해제 못하게 된다.
이럴 때는 프로젝트 속성 -> 공용속성 -> 프레임워크 및 참조 -> 참조제거를 수행하면 된다.
공용속성 프레임워크로 참조되어 발생하는 원인으로 Visual C++ 2012 하위버전에서 2012 버전으로 프로젝트를 업그레이드 할경우 생길 수 있다.
이것은 다른 프로젝트에 종속성 때문에 생기는 것으로 보통 해결 방법으로 프로젝트 종속성 팝업 메뉴에서 종속 프로젝트를 해제하려 하지만 "이 종속성은 프로젝트 시스템에서 추가했으며 제거할 수 없습니다" 라는 에러창이 뜨면서 종속성을 해제 못하게 된다.
이럴 때는 프로젝트 속성 -> 공용속성 -> 프레임워크 및 참조 -> 참조제거를 수행하면 된다.
공용속성 프레임워크로 참조되어 발생하는 원인으로 Visual C++ 2012 하위버전에서 2012 버전으로 프로젝트를 업그레이드 할경우 생길 수 있다.
Visual C++ 2012 콘솔 창 바로 닫히는 현상 해결하기
보통 Visual Studio 에서 콘솔 프로그램을 수행하고 종료되면
"계속하려면 아무 키나 누르십시오..."
라는 문자가 나오면서 사용자 입력을 기다려 주기 때문에 콘솔창의 내용을 확인할 수 있다.
그런데 Visual Studio 2012 사용하여 콘솔창을 실행하였을때 정상적인 경우에도 콘솔창이 바로 닫혀버리는 경우 있다.
이럴때는 다음과 같은 방법으로 해결할 수 있다.
프로젝트속성(alt+f7) -> 구성 속성 -> 링커 -> 시스템 -> 하위 시스템 -> 콘솔(/SUBSYSTEM:CONSOLE) 선택
참고로 다음과 같이 링커 옵션으로 줄 수 있다.
#pragma comment(linker, "/subsystem:windows") // 윈도우 프로그램 시작시
#pragma comment(linker, "/subsystem:console") // 콘솔 프로그램 시작시
"계속하려면 아무 키나 누르십시오..."
라는 문자가 나오면서 사용자 입력을 기다려 주기 때문에 콘솔창의 내용을 확인할 수 있다.
그런데 Visual Studio 2012 사용하여 콘솔창을 실행하였을때 정상적인 경우에도 콘솔창이 바로 닫혀버리는 경우 있다.
이럴때는 다음과 같은 방법으로 해결할 수 있다.
프로젝트속성(alt+f7) -> 구성 속성 -> 링커 -> 시스템 -> 하위 시스템 -> 콘솔(/SUBSYSTEM:CONSOLE) 선택
참고로 다음과 같이 링커 옵션으로 줄 수 있다.
#pragma comment(linker, "/subsystem:windows") // 윈도우 프로그램 시작시
#pragma comment(linker, "/subsystem:console") // 콘솔 프로그램 시작시
Visual C++ 링크 파일(*.map) 생성
# .exe .dll 빌드시 .map 파일을 생성하도록 하면 로딩되는
# obj, 변수 및 함수에 대한 시작주소등을 파악하여
# 런타임시 발생되는 오류(0x00... 주소를 나타내는) 발생시
# 디버깅에 활용 할 수 있다.
# Visual C++ 에서 .map 파일 생성하기
프로젝트 속성 -> 링크 -> 디버깅 -> 맵 파일 생성 -> 예
# .map 파일은 크게 다음의 3가지로 구분된다.
# 코드영영과 데이터영역의 기본 시작 주소
Start Length Name Class
# 전역 변수 및 일반 함수에 대한 주소
# obj 정보(보통 이부분에서 오류 주소를 찾아보면 된다.)
Address Publics by Value Rva+Base Lib:Object
# 정적 변수 및 함수에 대한 주소, obj 정보
Static symbols
# 참고로 Linux 에선 실행파일(컴파일시 -g 옵션이 포함되어 있어야 함)을
# nm 명령어로 확인해 볼 수 있다.
# obj, 변수 및 함수에 대한 시작주소등을 파악하여
# 런타임시 발생되는 오류(0x00... 주소를 나타내는) 발생시
# 디버깅에 활용 할 수 있다.
# Visual C++ 에서 .map 파일 생성하기
프로젝트 속성 -> 링크 -> 디버깅 -> 맵 파일 생성 -> 예
# .map 파일은 크게 다음의 3가지로 구분된다.
# 코드영영과 데이터영역의 기본 시작 주소
Start Length Name Class
# 전역 변수 및 일반 함수에 대한 주소
# obj 정보(보통 이부분에서 오류 주소를 찾아보면 된다.)
Address Publics by Value Rva+Base Lib:Object
# 정적 변수 및 함수에 대한 주소, obj 정보
Static symbols
# 참고로 Linux 에선 실행파일(컴파일시 -g 옵션이 포함되어 있어야 함)을
# nm 명령어로 확인해 볼 수 있다.
Visual C++ xxx.sbr No such file or directory
[빌드시 다음과 같은 컴파일 에러가 발생하였을때]
xxx.sbr' 파일을 열 수 없습니다.: No such file or directory
[해결방법]
C/C++ -> 찾아보기 정보 -> 찾아보기 정보 사용 -> 없음
xxx.sbr' 파일을 열 수 없습니다.: No such file or directory
[해결방법]
C/C++ -> 찾아보기 정보 -> 찾아보기 정보 사용 -> 없음
Visual C++ project macro
출처 : MSDN
프로젝트의 속성 페이지 대화 상자에서 문자열을 입력할 수 있는 모든 부분에 다음과 같은 매크로를 사용할 수 있습니다. 이 매크로는 대/소문자를 구분하지 않습니다.
$(RemoteMachine)
디버그 속성 페이지에서 원격 컴퓨터 속성의 값으로 설정합니다. 자세한 내용은 C/C++ 디버그 구성에 대한 프로젝트 설정 변경을 참조하십시오.
$(References)
프로젝트에 추가된 참조 목록(세미콜론으로 구분)
$(ConfigurationName)
현재 프로젝트 구성의 이름(예: "Debug")
$(PlatformName)
현재 프로젝트 플랫폼의 이름(예: "Win32")
$(Inherit)
프로젝트 빌드 시스템에서 작성한 명령줄에 상속된 속성이 나타나는 순서를 지정합니다. 기본적으로 상속된 속성은 현재 속성의 맨 뒤에 나타납니다.1
$(NoInherit)
상속될 모든 속성이 상속되지 않도록 합니다. 형제 수준에서도 실행되지 않도록 하려면 $(StopEvaluating)을 사용합니다. $(NoInherit)를 사용하면 동일한 속성에 대한 모든 $(Inherit)가 무시됩니다.1
$(StopEvaluating)
실행 체인에 있는 매크로 실행을 즉시 중지합니다. $(StopEvaluating) 뒤에 나오는 모든 값은 매크로의 실행 값에 나타나지 않습니다. $(StopEvaluating)이 $(Inherit) 앞에 오는 경우 실행 체인의 현재 위치에 있는 상속된 값이 매크로 값에 연결되지 않습니다. $(StopEvaluating)은 $(NoInherit) 기능의 상위 집합입니다.
$(ParentName)
이 프로젝트 항목을 포함하는 항목의 이름. 부모 폴더 이름이나 프로젝트 이름입니다.
$(RootNameSpace)
응용 프로그램을 포함하는 네임스페이스(있을 경우)
$(IntDir)
중간 파일에 지정된 디렉터리 경로로서 프로젝트 디렉터리에 대해 상대적인 경로. 이 경로는 중간 디렉터리 속성의 값이 됩니다.
$(OutDir)
출력 파일 디렉터리의 경로로서 프로젝트 디렉터리에 대해 상대적인 경로. 이 경로는 출력 디렉터리 속성의 값이 됩니다.
$(DevEnvDir)
드라이브 + 경로로 정의되는 Visual Studio .NET의 설치 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(InputDir)
드라이브 + 경로로 정의되는 입력 파일의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectDir)와 같습니다.
$(InputPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 입력 파일의 절대 경로 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectPath)와 같습니다.
$(InputName)
입력 파일의 기본 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectName)과 같습니다.
$(InputFileName)
기본 이름 + 파일 확장명으로 정의되는 입력 파일의 파일 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectFileName)과 같습니다.
$(InputExt)
입력 파일의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectExt)와 같습니다.
$(ProjectDir)
드라이브 + 경로로 정의되는 프로젝트의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(ProjectPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 프로젝트의 절대 경로 이름.
$(ProjectName)
프로젝트의 기본 이름.
$(ProjectFileName)
기본 이름 + 파일 확장명으로 정의되는 프로젝트의 파일 이름.
$(ProjectExt)
프로젝트의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(SolutionDir)
드라이브 + 경로로 정의되는 솔루션의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(SolutionPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 솔루션의 절대 경로 이름.
$(SolutionName)
솔루션의 기본 이름.
$(SolutionFileName)
기본 이름 + 파일 확장명으로 정의되는 솔루션의 파일 이름.
$(SolutionExt)
솔루션의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(TargetDir)
드라이브 + 경로로 정의되는 빌드용 기본 출력 파일의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(TargetPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 절대 경로 이름.
$(TargetName)
빌드용 기본 출력 파일의 기본 이름.
$(TargetFileName)
기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 파일 이름.
$(TargetExt)
빌드용 기본 출력 파일의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(VSInstallDir)
Visual Studio .NET을 설치한 디렉터리.
$(VCInstallDir)
Visual C++ .NET을 설치한 디렉터리.
$(FrameworkDir)
.NET Framework를 설치한 디렉터리.
$(FrameworkVersion)
Visual Studio에서 사용되는 .NET Framework의 버전. $(FrameworkDir)와 함께 사용하면 Visual Studio에서 사용되는 .NET Framework 버전의 전체 경로를 나타냅니다.
$(FrameworkSDKDir)
.NET Framework를 설치한 디렉터리. .NET Framework는 Visual Studio .NET과 함께 또는 별도로 설치할 수 있습니다.
$(WebDeployPath)
웹 배포 루트에서 프로젝트 출력이 속한 상대 경로. RelativePath와 같은 값을 반환합니다.
$(WebDeployRoot)
<localhost>의 절대 경로(예: c:\inetpub\wwwroot).
$(SafeParentName)
올바른 이름 형식에서 바로 상위 항목의 이름. 예를 들어, 폼은 .resx 파일의 상위 항목입니다.
$(SafeInputName)
올바른 클래스 이름으로 정의되는 파일 이름(확장명은 제외).
$(SafeRootNamespace)
프로젝트 마법사에서 코드를 추가할 네임스페이스 이름. 이 네임스페이스 이름은 올바른 C++ 식별자에 사용할 수 있는 문자만 포함합니다.
$(FxCopDir)
fxcop.cmd 파일의 경로. fxcop.cmd 파일은 모든 Visual C++ 버전에 설치되어 있지는 않습니다.
프로젝트의 속성 페이지 대화 상자에서 문자열을 입력할 수 있는 모든 부분에 다음과 같은 매크로를 사용할 수 있습니다. 이 매크로는 대/소문자를 구분하지 않습니다.
$(RemoteMachine)
디버그 속성 페이지에서 원격 컴퓨터 속성의 값으로 설정합니다. 자세한 내용은 C/C++ 디버그 구성에 대한 프로젝트 설정 변경을 참조하십시오.
$(References)
프로젝트에 추가된 참조 목록(세미콜론으로 구분)
$(ConfigurationName)
현재 프로젝트 구성의 이름(예: "Debug")
$(PlatformName)
현재 프로젝트 플랫폼의 이름(예: "Win32")
$(Inherit)
프로젝트 빌드 시스템에서 작성한 명령줄에 상속된 속성이 나타나는 순서를 지정합니다. 기본적으로 상속된 속성은 현재 속성의 맨 뒤에 나타납니다.1
$(NoInherit)
상속될 모든 속성이 상속되지 않도록 합니다. 형제 수준에서도 실행되지 않도록 하려면 $(StopEvaluating)을 사용합니다. $(NoInherit)를 사용하면 동일한 속성에 대한 모든 $(Inherit)가 무시됩니다.1
$(StopEvaluating)
실행 체인에 있는 매크로 실행을 즉시 중지합니다. $(StopEvaluating) 뒤에 나오는 모든 값은 매크로의 실행 값에 나타나지 않습니다. $(StopEvaluating)이 $(Inherit) 앞에 오는 경우 실행 체인의 현재 위치에 있는 상속된 값이 매크로 값에 연결되지 않습니다. $(StopEvaluating)은 $(NoInherit) 기능의 상위 집합입니다.
$(ParentName)
이 프로젝트 항목을 포함하는 항목의 이름. 부모 폴더 이름이나 프로젝트 이름입니다.
$(RootNameSpace)
응용 프로그램을 포함하는 네임스페이스(있을 경우)
$(IntDir)
중간 파일에 지정된 디렉터리 경로로서 프로젝트 디렉터리에 대해 상대적인 경로. 이 경로는 중간 디렉터리 속성의 값이 됩니다.
$(OutDir)
출력 파일 디렉터리의 경로로서 프로젝트 디렉터리에 대해 상대적인 경로. 이 경로는 출력 디렉터리 속성의 값이 됩니다.
$(DevEnvDir)
드라이브 + 경로로 정의되는 Visual Studio .NET의 설치 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(InputDir)
드라이브 + 경로로 정의되는 입력 파일의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectDir)와 같습니다.
$(InputPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 입력 파일의 절대 경로 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectPath)와 같습니다.
$(InputName)
입력 파일의 기본 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectName)과 같습니다.
$(InputFileName)
기본 이름 + 파일 확장명으로 정의되는 입력 파일의 파일 이름. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectFileName)과 같습니다.
$(InputExt)
입력 파일의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다. 해당 프로젝트가 입력 파일인 경우 이 매크로는 $(ProjectExt)와 같습니다.
$(ProjectDir)
드라이브 + 경로로 정의되는 프로젝트의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(ProjectPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 프로젝트의 절대 경로 이름.
$(ProjectName)
프로젝트의 기본 이름.
$(ProjectFileName)
기본 이름 + 파일 확장명으로 정의되는 프로젝트의 파일 이름.
$(ProjectExt)
프로젝트의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(SolutionDir)
드라이브 + 경로로 정의되는 솔루션의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(SolutionPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 솔루션의 절대 경로 이름.
$(SolutionName)
솔루션의 기본 이름.
$(SolutionFileName)
기본 이름 + 파일 확장명으로 정의되는 솔루션의 파일 이름.
$(SolutionExt)
솔루션의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(TargetDir)
드라이브 + 경로로 정의되는 빌드용 기본 출력 파일의 디렉터리로서 뒤에는 백슬래시(\)가 붙습니다.
$(TargetPath)
드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 절대 경로 이름.
$(TargetName)
빌드용 기본 출력 파일의 기본 이름.
$(TargetFileName)
기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 파일 이름.
$(TargetExt)
빌드용 기본 출력 파일의 파일 확장명. 파일 확장명 앞에는 '.'이 붙습니다.
$(VSInstallDir)
Visual Studio .NET을 설치한 디렉터리.
$(VCInstallDir)
Visual C++ .NET을 설치한 디렉터리.
$(FrameworkDir)
.NET Framework를 설치한 디렉터리.
$(FrameworkVersion)
Visual Studio에서 사용되는 .NET Framework의 버전. $(FrameworkDir)와 함께 사용하면 Visual Studio에서 사용되는 .NET Framework 버전의 전체 경로를 나타냅니다.
$(FrameworkSDKDir)
.NET Framework를 설치한 디렉터리. .NET Framework는 Visual Studio .NET과 함께 또는 별도로 설치할 수 있습니다.
$(WebDeployPath)
웹 배포 루트에서 프로젝트 출력이 속한 상대 경로. RelativePath와 같은 값을 반환합니다.
$(WebDeployRoot)
<localhost>의 절대 경로(예: c:\inetpub\wwwroot).
$(SafeParentName)
올바른 이름 형식에서 바로 상위 항목의 이름. 예를 들어, 폼은 .resx 파일의 상위 항목입니다.
$(SafeInputName)
올바른 클래스 이름으로 정의되는 파일 이름(확장명은 제외).
$(SafeRootNamespace)
프로젝트 마법사에서 코드를 추가할 네임스페이스 이름. 이 네임스페이스 이름은 올바른 C++ 식별자에 사용할 수 있는 문자만 포함합니다.
$(FxCopDir)
fxcop.cmd 파일의 경로. fxcop.cmd 파일은 모든 Visual C++ 버전에 설치되어 있지는 않습니다.
build and install openssl
# OpenSSL 윈도우 빌드
1. openssl-1.0.1c.tar.gz 압축 해제
2. cd openssl-1.0.1c
3. 콘솔창에서 VC++ 사용할 수 있도록 환경 설정
"c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
4. perl 로 설정파일 만들기(perl 설치파일 http://downloads.activestate.com/ActivePerl/releases/)
win32 경우 ==> perl Configure VC-WIN32 --openssldir=C:\OpenSSL1.0.1
win64 경우 ==> perl Configure VC-WIN64A --openssldir=C:\OpenSSL1.0.1
5. 컴파일 환경 설정 배치 실행
win32 경우 ==> ms\do_ms.bat
win64 경우 ==> ms\do_win64a.bat
6. 빌드
.lib 빌드 ==> nmake -f ms\nt.mak install
.dll 빌드 ==> nmake -f ms\ntdll.mak install
7. 결과 확인
include 파일 ==> C:\OpenSSL1.0.1\include\openssl
.lib(.dll) 파일 ==> C:\OpenSSL1.0.1\lib
#####
# OpenSSL 리눅스 빌드
1. openssl-1.0.1c.tar.gz 압축 해제
tar zxvf openssl-1.0.1c.tar.gz
2. cd openssl-1.0.1c
3. 설정파일 만들기
./config --prefix=/home/ysoftman/openssl1.0.1
4. 빌드 후 테스트
make && make test
5. 설치
make install
6. 결과 확인
include 파일 ==> /home/ysoftman/openssl1.0.1/include/openssl
.a 파일 ==> /home/ysoftman/openssl1.0.1/lib
#####
# redhat, centos 에서 설치
sudo yum install -y pcre-devel
sudo yum install -y openssl-devel
# debian, ubuntu 에서 설치
sudo apt-get install -y libpcre3-dev
sudo apt-get install -y libssl-dev
sudo apt-get install -y libz-dev
#####
1. openssl-1.0.1c.tar.gz 압축 해제
2. cd openssl-1.0.1c
3. 콘솔창에서 VC++ 사용할 수 있도록 환경 설정
"c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
4. perl 로 설정파일 만들기(perl 설치파일 http://downloads.activestate.com/ActivePerl/releases/)
win32 경우 ==> perl Configure VC-WIN32 --openssldir=C:\OpenSSL1.0.1
win64 경우 ==> perl Configure VC-WIN64A --openssldir=C:\OpenSSL1.0.1
5. 컴파일 환경 설정 배치 실행
win32 경우 ==> ms\do_ms.bat
win64 경우 ==> ms\do_win64a.bat
6. 빌드
.lib 빌드 ==> nmake -f ms\nt.mak install
.dll 빌드 ==> nmake -f ms\ntdll.mak install
7. 결과 확인
include 파일 ==> C:\OpenSSL1.0.1\include\openssl
.lib(.dll) 파일 ==> C:\OpenSSL1.0.1\lib
#####
# OpenSSL 리눅스 빌드
1. openssl-1.0.1c.tar.gz 압축 해제
tar zxvf openssl-1.0.1c.tar.gz
2. cd openssl-1.0.1c
3. 설정파일 만들기
./config --prefix=/home/ysoftman/openssl1.0.1
4. 빌드 후 테스트
make && make test
5. 설치
make install
6. 결과 확인
include 파일 ==> /home/ysoftman/openssl1.0.1/include/openssl
.a 파일 ==> /home/ysoftman/openssl1.0.1/lib
#####
# redhat, centos 에서 설치
sudo yum install -y pcre-devel
sudo yum install -y openssl-devel
# debian, ubuntu 에서 설치
sudo apt-get install -y libpcre3-dev
sudo apt-get install -y libssl-dev
sudo apt-get install -y libz-dev
#####
# mac(darwin) 에서 설치
brew install openssl
# openssl-devel 가 없기 때문에 openssl 의 include, lib 파일을 링크해준다.
echo 'y' | ln -s /usr/local/opt/openssl/include/openssl /usr/local/include
echo 'y' | ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib
# 다음 옵션들로 현재 참고하고 있는 include <...>, LIBRARY_PATH 설정을 파악할 수 있다.
# -x 언어
# -v verbose
# -E 지정된 장치(stage)에서 preprocessor 만 수행한다.
g++ -x c++ -v -E /dev/null
brew install openssl
# openssl-devel 가 없기 때문에 openssl 의 include, lib 파일을 링크해준다.
echo 'y' | ln -s /usr/local/opt/openssl/include/openssl /usr/local/include
echo 'y' | ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib
# mac 기본 openssl(LibreSSL) 이 있다.
# /usr/bin/openssl # openssl(LibreSSL)
# openssl(OpenSSL) 을 설치하면 다음 경로에 생성된다.
# /usr/local/opt/openssl/bin/openssl # openssl(OpenSSL)
brew install openssl
# /usr/local/opt/openssl/bin/openssl 이 우선 하는지 확인
which -a openssl
/usr/local/opt/openssl/bin/openssl
/usr/bin/openssl
# openssl(OpenSSL) 경로를 우선하지 않다면 우선하도록 PATH 환경변수 변경하자.
export PATH=/usr/local/opt/openssl/bin/openssl:$PATH
#####
# 다음 옵션들로 현재 참고하고 있는 include <...>, LIBRARY_PATH 설정을 파악할 수 있다.
# -x 언어
# -v verbose
# -E 지정된 장치(stage)에서 preprocessor 만 수행한다.
g++ -x c++ -v -E /dev/null
Visual C++ .def 파일에서 .lib 파일 만들기
.lib 를 통해 .dll 을 암묵적으로 링크해서 사용하고 싶은 경우, lib 유틸리티로 .def 를 .lib 로 만들 수 있다.
lib는 아래 그림과 같이 ..\VC\bin 에 존재한다.
다음과 같이 .def 파일과 machine 옵션을 지정하면 .lib .exp 파일이 생성된다.(예: sqlite)
lib는 아래 그림과 같이 ..\VC\bin 에 존재한다.
다음과 같이 .def 파일과 machine 옵션을 지정하면 .lib .exp 파일이 생성된다.(예: sqlite)
Windows 7(32/64bit) 에 Visual Studio 6.0 설치 문제 발생시 해결방법
윈도우 7 (32/64bit) 에 VisualStudio 6.0 설치시 문제가 발생 할 수 있다.
보통 많이 나타나는 것은 "설치된 구성 요소를 찾는 중입니다" 에서 더 이상 진행이 되지 않고 "프로그램 응답 없음" 상태로 되버리는 것이다. 이와 같은 문제를 해결하기 위해서 설치 실행 파일 (SETUP.EXE) 를 아래 그림과 같이 호환 모드로 실행한다.
보통 많이 나타나는 것은 "설치된 구성 요소를 찾는 중입니다" 에서 더 이상 진행이 되지 않고 "프로그램 응답 없음" 상태로 되버리는 것이다. 이와 같은 문제를 해결하기 위해서 설치 실행 파일 (SETUP.EXE) 를 아래 그림과 같이 호환 모드로 실행한다.
Visual C++ 2008 Project : error PRJ0019: 도구에서 오류 코드를 반환했습니다.... 해결방법
[에러 내용]
Project : error PRJ0019: 도구에서 오류 코드를 반환했습니다. 위치: "빌드 후 이벤트를 수행하고 있습니다..."
[해결 방법]
Visual C++ 2008 의 경우
프로젝트 속성(ALT-F7)-> 구성 속성 -> 빌드 이벤트 -> 상황에 맞게 빌드 전, 링크 전, 빌드 후 에서 명령줄의 에러를 체크한다.
Project : error PRJ0019: 도구에서 오류 코드를 반환했습니다. 위치: "빌드 후 이벤트를 수행하고 있습니다..."
[해결 방법]
Visual C++ 2008 의 경우
프로젝트 속성(ALT-F7)-> 구성 속성 -> 빌드 이벤트 -> 상황에 맞게 빌드 전, 링크 전, 빌드 후 에서 명령줄의 에러를 체크한다.