라이브러리 소스를 링크하는 대신 라이브러리 소스를 추가해야합니까?


14

저는 C ++을 처음 접하므로 작은 종속성 (예 : 스크립팅 언어 또는 JSON / YAML / XML 파서)을 어떻게 가장 잘 처리해야하는지 잘 모르겠습니다.

별도의 프로젝트를 만들어 정적 라이브러리로 연결해야합니까, 아니면 .h / .cpp 파일을 기본 프로젝트에 넣는 단점이 있습니까?

후자는 호환되지 않는 라이브러리 (라이브러리를 빌드 할 때 다른 컴파일러 설정)를 처리하는 데 몇 시간을 보냈으므로 C ++을 잘못 배우는 것을 시작하고 싶지 않습니다.

별도의 라이브러리로 유지하는 것이 바람직하다면 .lib / .a 파일이 내 응용 프로그램에 성공적으로 연결되도록 컴파일 플래그를 어떻게 동기화하는 것이 가장 좋습니까?

(현재 MSVC 2015로 작업하고 있지만 목표는 XCode / clang을 사용하여 Mac OS X 및 iOS에서 컴파일하는 것이므로 적어도 3 가지 유형의 라이브러리 (Win x86, Mac x64, ARM)를 처리해야합니다 )


5
ABIss를 응시하고 그들은 당신을 볼 것입니다
Basilevs

1
일부 라이브러리는 이러한 방식으로 사용 되도록 고안 되었습니다. SQLite는 라이브러리가 선호하는 사용 패턴은 실행 파일로 컴파일에 C 또는 C ++ 응용 프로그램의 소스 트리에 병합 된 소스와 헤더 파일을 드롭하는 것입니다.
Mark Benningfield

답변:


6

TLDR;

소스 추가 해야합니까 ? X 는 소스를 추가
해야합니까 ? 의존

이유는 다음과 같습니다.

당시에는 컴파일 시간이 더 작은 프로젝트의 문제였습니다. 소스를 컴파일하고 컴파일러 결과를 캐싱하는 것에 대해 걱정하지 않는 것이 분명히 매력적이었습니다. 그것은 당신과 관련이없는 도서관을위한 한 가지 포인트입니다.

또 다른 중요한 것은 버전 관리입니다. 각 라이브러리를 개별적으로 버전 화해야합니까? 각각에 대해 테스트를 실행 하시겠습니까? 많은 팀원에게 배포 하시겠습니까? 라이브러리는 사용하면 훌륭하고 이동하기 편리하지만 다시는 신경 쓰지 않는 것 같습니다.

마지막 요점은 오버 헤드가 추가되어 소스 파일을 삭제하는 것이 더 쉽다는 것입니다. 라이브러리를 사용하지 않고 소스를 삭제하는 것이 매우 중요합니다. 아시다시피, 단일 컴파일러 설정을 변경 한 후에는 모든 종속성을 추적해야합니다.

나는 경험 에서이 모든 것을 알고 있습니다.

Swift 프로젝트의 경우 Xcode를 사용하여 구성하기 쉽기 때문에 프레임 워크 (라이브러리)를 사용하고 링크합니다. 또한 버전 관리, 테스트 및 디커플링이 필요하므로 그 이유가 있습니다.

Mono (C #) 프로젝트의 경우 Unity의 경우 프로젝트를 라이브러리로 세분화하고 각 라이브러리를 컴파일하고 테스트하는 힙 접근 방식으로 시작했습니다.하지만 라이브러리를 Unity에 드롭하면 모든 종류의 문제가 발생했습니다. , Mono Unity의 해킹 버전에서 플랫폼을 변경할 때 코드가 가끔 다르게 나타나는 동작을 사용합니다. 모든 라이브러리를 관리하기 위해 여기에 단일 IDE가없는 것은 정말 고통스러운 일이므로 모든 소스를 Unity에 배치하는 것은 생산성면에서 큰 승리였습니다.

마지막으로, 내가 작업 한 C ++ 게임 프로젝트 인 당신과 가장 관련이 있습니다. 이 엔진을 위해 게임 엔진, 네트워크 실시간 클라이언트, 네트워크 HTTP 클라이언트, AI 및 지속성 저장소가 클라이언트 측에서 작성되었습니다. 무엇을 선택 했습니까? CLion + 라이브러리. 라이브러리를 사용하고 있었지만 느낌이 들지 않았습니다. 모든 소스는 CLion IDE 프로젝트에 있었고 CMakeList를 작성하여 모든 빌드를 트리거하고 단일 스트로크로 링크 할 수있었습니다.

결론적으로 , 라이브러리 사용은 미래를 보장하는 솔루션이지만 필요하지 않은 경우 조기 최적화라고 말할 수 있습니다. 내가 당신의 상황에서 확인할 수있는 한, 다중 빌드 대상을 가지고 있다면 MSVC에서 Xcode로 전환하는 것이 고통 스럽습니다. 그래서, 그냥 그것을 삭제하고 시간은 당신이 때 경우에 가능한 한 분리로 유지 수있는 라이브러리를 사용할 필요가있다.

추신 : 요즘 도커와 비슷한 딜레마가 있습니다. 내가 작곡해야합니까? 방금 로컬로 실행해야합니까? 같은 응용 프로그램 내에서 응용 프로그램을 빌드 할 수 있기 때문에 Elixir도 있습니다. 아니면 앱을 소위 마이크로 서비스로 분리합니까? ... 등.은 총알이 없으므로 항상 YMMV로 자신을 측정하십시오.


2

C ++ 라이브러리와의 연결에는 많은 번거 로움이 필요하며 올바르게 수행하려면 많은 지식과 노력이 필요합니다. C ++ 학습자들에게 위협이 될 수 있습니다.


종종 특정 C ++ 라이브러리의 제작자 / 관리자가이를 염두에두고 어떤 방법 으로든 권장합니다.

즉, 작성자 / 유지 업체가 라이브러리를 헤더 (* .h 및 .hpp 만 해당)로 포함 시키거나 소스 ( .h * 또는 .c )로 포함 시키려는 경우 읽어보기에서 매우 명확하게 말했을 것입니다. 또는 문서.


크로스 플랫폼으로 설계되고 유지 관리되는 (및 여러 C ++ 컴파일러 공급 업체 및 환경과 호환되는) 라이브러리에는 종종 makefile 시스템 또는 빌드 구성 시스템 (예 : CMake)이 있습니다. 이러한 시스템은 플랫폼 차이를 완화하는 헤더 shim을 생성하고 올바른 명령 행 옵션을 사용하여 올바른 순서로 소스 파일에서 컴파일러와 링커를 호출하는 스크립트를 생성하는 데 사용됩니다. 플랫폼 및 구성에 따라 이러한 빌드 시스템은 특정 헤더 또는 소스 파일을 포함하거나 제외하거나 특정 전 처리기 기호를 정의하거나 정의하지 않을 수 있습니다.


저자 / 유지 업체 권장 사항에 반하는 것이 가능하지만 항상 광범위한 포팅 노력이 필요합니다. 해당 포팅 작업에 필요한 작업량은 다른 C ++ 환경으로 포팅하는 것과 비슷할 수 있습니다.


Visual C ++는 프로젝트 설명 파일 (부분 XML 기반)을 기반으로하는 자체 빌드 시스템을 사용하기 때문에 Linux에서 사용되는 스크립팅 기반 빌드 시스템과는 다릅니다. CMake에서 사용하는 방식은 CMake가 구성 설정을 가져 와서 * .vcxproj 파일에 구워진 구성 옵션을 사용하여 전체 Visual C ++ 프로젝트 구조를 내보내는 것입니다.

Visual C ++와의 C ++ 연결 중에 문제가 발생하면 Visual Studio GUI를 사용하여 프로젝트 속성 페이지 대화 상자를 사용하여 * .vcxproj 파일의 빌드 설정을 수정할 수 있습니다. 이것은 12 가지 중요한 C ++ 컴파일 및 링크 설정의 의미와 결과를 완전히 이해한다고 가정합니다.

이제 Visual C ++ 사용의 가장 어리석은 부분이 있습니다. 수십 개의 다른 타사 라이브러리를 사용하는 경우 모든 빌드 설정을 변경하면 각 * .vcxproj 파일로 이동하고 GUI에서 수십 동안 동일한 변경을 반복해야합니다 타임스. 번거롭지 만 올바르게 수행하는 방법을 알고 있다면 완료 할 수 있습니다.

대부분의 Visual C ++ 학습자는 오류 코드로 식별되는 Visual C ++ 컴파일러 및 링커 오류를 관찰하여 이러한 설정을 어려운 방식으로 학습합니다. 예를 들어, "기호 기호가 두 번 이상 정의되었습니다"라는 피상적 인 의미로 LNK2005를 조회 할 수 있지만, 중복 정의가 부주의 한 프로그래밍 실수로 발생하지 않는다는 것을 이해하면 일부는 컴파일 및 링크 옵션의 충돌 또는 오용


상황에 대해보다 구체적이고 유용한 답변을 제공하려면 사용하려는 라이브러리의 이름과 연결 오류 또는 발생하는 기타 어려움을 알아야합니다. 해당 라이브러리의 토론 게시판에서 해당 질문에 대한 기존 답변을 찾을 수 있습니다. 이러한 질문은 "링크 문제", "창"및 "시각적 C ++"로 태그되는 경향이 있습니다.

이 문제에 대한 초보자부터 전문가까지의 가이드가 가능하지만 프로젝트마다 다를 것입니다. 다른 프로젝트에서 선택한 다른 환경 설정은 가이드를 완전히 다시 작성해야합니다.


CMake를 사용하여 .vcxproj를 내보내는 대신 .vcxproj를 수정하는 경우 CMake 구성을 수정할 수 있습니다
Caleth

1

더 쉬운 한 나는 그렇다고 말할 것입니다. 많은 장점이 있습니다 :

  1. 특히 링크 시간 최적화를 설정하면 더 빠르고 더 나은 코드가 생성됩니다.

  2. IDE는 더 좋아할 것입니다. 예를 들어 인터페이스 (.h)가 아니라 라이브러리 코드 의 구현 (.cpp)으로 건너 뛸 수 있습니다. 잘못 문서화 된 코드 (예 : 대부분의 코드).

  3. 종종 의존성을 git 서브 모듈로 추가 할 수 있습니다.이 서브 모듈은 약간 해킹이지만 실제로는 의존성을 갖는 꽤 좋은 방법입니다 (어쨌든 C ++의 경우에는 건전한 빌드 시스템이 거의 없습니다). 라이브러리를 업데이트하고 다른 버전을 테스트하기가 정말 쉽습니다.

  4. 예를 들어 2017을 사용하는 동안 MSVC ++ 2013으로 컴파일되는 종속성에 대해 걱정할 필요가 없습니다. 또는 공유 대 정적 MSVCRT.

  5. 디버그 모드에서 쉽게 빌드하고 라이브러리로 들어갈 수 있습니다.

내가 이것을하고 싶지 않다고 생각하는 유일한 이유 는 라이브러리가 크고 부스트 또는 LLVM과 같이 복잡한 빌드 시스템을 가지고 싶지 않은 경우입니다. 그러나 간단한 라이브러리의 경우 실제로 단점이 없습니다.

예를 들어, 몇 가지 프로젝트에서 libusb를 사용하므로 Windows를 지원해야합니다. libusb는 빌드 시스템의 농담이며 실제로 Windows에서는 작동하지 않는 autotools를 사용합니다. 사전 컴파일 된 바이너리를 제공하지만 MSVC ++ 2013으로 빌드되었으며 2017에서는 작동하지 않습니다. 지금까지 가장 쉬운 해결책 모든 관련 .c 및 .h 파일을 내 프로젝트에 추가하는 것입니다.


2
1) 정말로? 정적 라이브러리는 방금 컴파일 한 것처럼 오브젝트 파일의 모음입니다.
Baldrickk

.o컴파일 된 파일 의 아카이브를 만들 수는 -flto있지만 실제로 정적 라이브러리는 아닙니다. Clang의 경우 LLVM 비트 코드 파일입니다. 그리고 다른 사람이 제공하는 정적 라이브러리를 사용하면 분명히 작동하지 않습니다.
Timmmm

좋아,이 토론을 업그레이드하자 -나는 더 많은 것들을 배우기를 기대합니다 :)
Baldrickk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.