[C/C++] error LNK2005: 이미 정의되어 있습니다. (빌드에서 제외)

윤찬호·2023년 1월 19일
0

에러

목록 보기
3/6

현상

A.lib(base64.obj) : error LNK2005: _Base64_EncodeFile이(가) B.lib(base64.obj)에 이미 정의되어 있습니다.

원래 C 프로젝트는(메인 프로젝트) A.lib 파일을 사용한다.

A 프로젝트는 base64.h, base64.c 파일을 포함하고 있어 A프로젝트를 컴파일 하면 base64.obj 파일이 생성된다.

그런데 C 프로젝트에서 추가적인 기능이 필요하여 B.lib 파일을 사용해야 하는 상황이 왔다.

문제는 B 프로젝트 또한 base64.h, base64.c 파일을 포함하고 있어 컴파일 하면 base64.obj 파일이 생성된다는 것이다.

C 프로젝트를 빌드할 때 A.lib, B.lib를 사용하는 데 두 개의 lib 안에 base64.obj가 중복으로 링크되어 있어 해당 에러가 발생했다.

해결

위에서 발생한 오류의 원인은 A, B 프로젝트에서 중복으로 base64.obj를 생성한다는 것이다.

B 프로젝트를 빌드할 때 base64.h, base64.c 파일을 제거하고 빌드를 하면 base64.obj 파일이 생성 및 링크되지 않기 때문에 A.lib 파일과 함께 사용할 수 있다.

하지만, 이렇게 할 경우 기존에 B.lib를 사용하던 D 프로젝트에서 문제가 발생한다.
B.lib를 가지고 D 프로젝트를 빌드하면 LNK1120, LNK2019, LNK2001 확인할 수 없는 외부 기호(참조) 에러가 발생한다.

결국 B 프로젝트에서 함부로 base64 관련 파일을 제거할 수 없는 것이다.

CASE 1

프로젝트에서 해당 파일을 완전히 제거 하는것이 아니라 빌드할 때만 해당 파일을 제외하기.

base64.c (base64.h) 파일의 속성 페이지에서 "빌드에서 제외" 옵션을 사용한다.

이렇게 설정하면 소스 파일에서는 '-'가 표시된 빨간색 동그라미 모양이 표시되고, 프로젝트를 빌드하면 base64.obj 파일이 생성되지 않는다.

이때, "내용" 부분에 자세히 기록하여 다른 사람이 봤을 때 왜 '빌드에서 제외' 옵션을 사용했는지 알 수 있도록 하자.

CASE 2

전처리기를 이용하여 소스 코드를 넘겨 버린다.

// ex) base64.c

#ifndef _USING_C_PROJECT_ // C 프로젝트 에서 사용할 떄는 아래 코드를 사용하지 않는다.

#include "base64.h"

int Base64_EncodeFile(char *pszEncodeFile, char *pszOutputFile) { ... }
int Base64_DecodeFile(char *pszDecodeFile, char *pszOutputFile) { ... }
...

#endif

위와 같이 전처리기를 이용해서 문제가 되는 함수들을 패스 시킨다.

이렇게 하고 빌드를 하면 base64.obj 파일은 생성되지만 실제적으로 내용이 비어 있기 때문에 A.lib 파일과 함께 사용해도 LNK2005 에러가 발생하지 않는다.


솔직히 두 가지 방법 모두 마음에 들진 않는다...

그래도 이렇게 함으로써 급한 불은 끌 수 있다.

0개의 댓글