※ 정적 라이브러리를 제대로 가져오려면 헤더 파일도 제대로 가져와야 동작한다. 아래의 포스트를 참고.
[Visual Studio] - #include 따옴표(")와 꺾쇠(<>)의 차이
1) 와 같은 표준 라이브러리의 헤더 파일들은 도대체 어디서 가져오는 것이냐?2) , 와 같은 윈도우즈 개발 시 사용하는 헤더 파일들은 도대체 어디서 가져오냐?3) 내가 만든 라이브러리의 헤더파
linocraft.tistory.com
▷ Visual Studio에서는 솔루션을 단위로 빌드를 수행하며, 그 아래에 다양한 프로젝트들을 만들 수 있다. 아래와 같이, 하나는 시작 프로젝트로서 main()이 있는 실행 파일(exe)을 생성하는 프로젝트와, 다른 하나는 lib 파일을 만드는 정적 라이브러리 프로젝트다.
▷ 우선, 각 프로젝트를 컴파일하면 파일마다 재배치 가능한 오브젝트 파일(obj)이 만들어진다. 이 오브젝트 파일들은 링커가 처리해서 최종적인 실행 파일과 라이브러리로 통합한다.
▷ Visual Studio에서 링커에게 정적 라이브러리의 위치를 알려주는 방법은 아래와 같이 [참조]에 정적 라이브러리 프로젝트를 추가해주는 것이다. 아주 간단하다. 그러나 추천하진 않는다.
▷ 이러한 방식은 링커의 작동 방식과 세부 조정 사항을 숨기므로 개인적으로 선호하는 스타일은 아니다.
▷ 다른 방식으로는 #pragma 키워드를 사용해 라이브러리를 알려주는 것인데, 이것은 철저하게 VS컴파일러와 Visual Studio에 특화된 키워드이므로 마냥 좋다고 할 수는 없다. 윈도우즈 기반으로 개발할 것이라면 이 키워드를 써도 상관은 없으나, 언젠가는 내가 쓴 코드를 가지고 다양한 플랫폼에 CMake 같은 도구로 크로스 빌드할 상황도 올 수 있다. 플랫폼(OS) 및 빌드 환경(Visual Studio MSBuild, MSVC)에 특화된 개념의 사용은 되도록 지양하는 것이 좋다.
※ 물론 윈도우즈에서 동작하는 DirectX 기반의 프로젝트의 경우 #pragma comment(lib, d3d12) ... 이런 형태로 DirectX 관련 라이브러리를 지정하는 편이다. 이렇게 하면 컴파일 단계에서 obj(coff) 파일에 참조할 라이브러리 '이름'이 포함되며, 이것을 링커가 참조하는 방식이다. 이제 경로를 찾아야 하는데, 링커는 [추가 라이브러리 디렉터리](명령 옵션)나 [라이브러리 디렉터리](환경변수LIB)의 경로로 라이브러리를 찾는다. Visual Studio는 DirectX의 라이브러리가 있는 Windows SDK 디렉터리를 [포함 디렉터리]에 자동으로 추가해주므로 링커는 여기서 DirectX 관련 lib 파일을 찾을 수 있다. 여하튼, 이러한 방식은 DirectX가 윈도우즈에 종속된 라이브러리이므로 아예 프로젝트 자체의 성격이 Windows 기반 MSVC 빌드 환경임이 확실시 되는 경우라서 가능한 이야기다.
▷ 따라서 가장 전통적인 방식이 좋다. 링커에게 1) 라이브러리 이름과, 2) 라이브러리 파일의 경로를 알려주는 것이다. 어떤 환경의 툴(gcc, clang, msvc, ...)이든 상관 없이 대부분의 링커는 사용자가 알려준 경로에 찾아가서 이름으로 lib를 검색하기 때문이다.
▷ 먼저 main()가 있는 프로젝트의 속성 페이지를 보면 [링커]의 [입력]에 [추가 종속성] 항목이 있다. 이것이 링커에게 정적 라이브러리의 이름을 직접 알려주는 옵션을 활성화하는 것이다.
▷ 세미콜론(;)으로 라이브러리들을 구분해줄 수 있다. 미리 작성된 키워드는 건드리지 말자! 이들은 kernel32.lib, user32.lib 등 아주 기본적인 windows api 라이브러리인데, 이들은 CRT 런타임 라이브러리 등 많은 windows 기반 라이브러리들이 참조하기 때문에 VS가 편의적으로 설정해준 것이다. 여하튼, [추가 종속성]에 우리의 정적 라이브러리인 MyStaticLib.lib를 작성해주면 된다.
▷ 마지막으로 [링커]의 [일반]의 [추가 라이브러리 디렉터리]에 경로를 지정해주는 일이다. 외부에서 가지고 온 정적 라이브러리는 어딘가에 저장될 것이다. 그 경로를 입력하면 된다. 만약 같은 솔루션 아래에 만든 정적 라이브러리라면 최종 빌드 결과물(lib파일)의 경로를 알고 있을 것이므로 그것을 입력해주면 된다. 내 프로젝트의 경우, 위와 같은 경로에 내 정적 라이브러리 프로젝트의 빌드 결과물이 가는 곳을 입력했다.
▷ [추가 종속성]과 [추가 라이브러리 디렉터리] 설정은 vscproj xml 파일에 등록되고, 이것을 MSBuild가 읽어서 링커에게 명령줄의 옵션으로 전달한다. 프로젝트 단위로 설정을 다르게 가져갈 수 있으므로, 프로젝트마다 링커의 옵션을 다르게 설정할 수 있다.
▷ 이때 이와 관련하여 다음 사항을 주의하자. 아래 그림처럼 [라이브러리 디렉터리]를 변경하는 방식도 있으나 이건 되도록 건드리지 말자는 것...! [VC++ 디렉터리] - [라이브러리 디렉터리]는 컴파일러의 전역 설정이므로 대부분의 프로젝트에서 사용하는 아주 중요한 라이브러리 파일들(C/C++ 표준 라이브러리, Windows SDK, ...)의 위치가 설정되어 있다. [추가 라이브러리 디렉터리]를 변경하자.
▷ [라이브러리 디렉터리]는 환경변수 LIB에 해당한다고 나와있다. MSBuild가 빌드 시 이 값을 세션 환경 변수 LIB에 등록해준다. 링커가 라이브러리 파일을 찾을 때는 먼저 명령 옵션에 설정된 경로부터 찾고, 못 찾으면 이 LIB 환경변수에 설정된 경로를 검색한다. 즉, 전역 설정이므로 보통은 C/C++ 표준 라이브러리, Windows SDK로 다운받은 주요 라이브러리들이 들어간다. 따라서 외부의 정적 라이브러리 경로를 여기에 설정하지 말자!
'IT 공부 > Visual Studio 툴 사용하기' 카테고리의 다른 글
[Visual Studio] - 문자 집합 옵션과 UNICODE 매크로 (0) | 2024.12.26 |
---|---|
[Visual Studio] - CRT 런타임 라이브러리의 빌드 방식 (0) | 2024.12.26 |
[Visual Studio] - #include 따옴표(")와 꺾쇠(<>)의 차이 (1) | 2024.12.24 |
[Visual Studio] - 소스파일과 빌드 산출물을 깔끔하게 구성하는 방법 (0) | 2024.12.23 |
[Visual Studio] - 소스코드를 가져오거나 컴파일할 때 한글 인코딩 문제 (0) | 2024.12.21 |