1

네트워크 장치 용 API로 출시 할 정적 라이브러리를 빌드하려고합니다. 나는 성공적으로 컴파일하고 출력 파일을 lib 디렉토리 생성하는 라이브러리를 연결, 다음과 같이 나는 디렉토리 구조로 재배치 할 수 다음 MyLibConfig.cmake 파일이 매우 간단하고, 포함정적 부스트 빌드를 VS2012 및 Win32/64에서 정적 라이브러리로 연결

EyeLib 
L-Include 
| L-PublicInterface.h 
L-Lib 
| L-debug 
| | L-MyLib.lib 
| | L-MyLib.pdb 
| L-release 
|  L-MyLib.lib 
L-MyLibConfig.cmake 

:

# the header file is relative to this cmake file, so get the path. 
GET_FILENAME_COMPONENT(MyLib_TOPLEVEL_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) 
SET(MyLib_INCLUDE_DIR ${MyLib_TOPLEVEL_DIR}/include) 

IF(WIN32) 
    FIND_LIBRARY(MyLib_DEBUG_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/debug) 
    FIND_LIBRARY(MyLib_RELEASE_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/release) 
    SET(MyLib_LIBRARIES optimized ${MyLib_RELEASE_LIBRARY} debug ${MyLib_DEBUG_LIBRARY}) 
ENDIF(WIN32) 
IF(UNIX) 
    FIND_LIBRARY(MyLib_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib) 
    SET(MyLib_LIBRARIES "${MyLib_LIBRARY}") 
    MARK_AS_ADVANCED(MyLib_LIBRARY) 
ENDIF(UNIX) 

# handle the QUIETLY and REQUIRED arguments 
INCLUDE(FindPackageHandleStandardArgs) 
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MyLib DEFAULT_MSG MyLib_LIBRARIES MyLib_INCLUDE_DIR) 

MARK_AS_ADVANCED(MyLib_INCLUDE_DIR) 

이 빌드 구조는 과거 빌드 한 테스트 라이브러리에서 작동했지만 간단한 테스트 응용 프로그램을 빌드 할 때 링크 오류가 발생합니다. "LNK1104 오류 : libboost_thread 파일을 열 수 없습니다. -vc110-mt-s-1_54.lib ' "

나는 할 수있다. 라이브러리 빌드와 동일한 프로젝트에 추가하면 테스트 응용 프로그램이 성공적으로 빌드되고 실행됩니다. 라이브러리 빌드가 링크 할 부스트 라이브러리를 찾고 있기 때문에 프로젝트의 실행 파일로 전파됩니다.

b2 링크 = 정적 런타임 링크 = 정적 스레드 = 다중 변형 = 디버그로 부스트 1.54를 빌드했습니다. --layout = 태그가 붙어 있으며 라이브러리 빌드와 테스트 응용 프로그램 빌드가 모두 정적 MSVC 런타임 (/ MT).

누구나이 도움말을 통해 도움/조언/추가 테스트를 제공 할 수 있습니까? 모든 부스트 도구가 API 라이브러리에 컴파일되어 있는지 확인해야하므로 클라이언트가 직접 설치해야 할 필요가 없습니다.

set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib") 

set(Boost_USE_STATIC_LIBS ON) 
set(Boost_USE_MULTITHREADED ON) 
find_package(Boost REQUIRED COMPONENTS system date_time regex thread chrono) 
if(NOT WIN32) 
    list(APPEND Boost_LIBRARIES pthread) 
endif() 

include_directories(${Boost_INCLUDE_DIRS}) 

FILE(GLOB srcs *.cpp) 
FILE(GLOB headers *.h) 
set(libname MyLib) 

set(deps ${Boost_LIBRARIES}) 

#To allow compilation. std=c++0x is for accepting the access to enums, which usually is just accepted with Visual Studio 
IF(NOT WIN32) 
    set (CMAKE_CXX_FLAGS "-fpermissive -std=c++0x") 
ENDIF(NOT WIN32) 

SOURCE_GROUP(${libname} FILES ${srcs}) 
SOURCE_GROUP("${libname}\\Hdr" FILES ${headers}) 
add_library(${libname} ${srcs} ${headers}) 
target_link_libraries(${libname} ${deps}) 

답변

7

이것은 의도적으로 설계된 :

은 도움에서-경우

정보 추가, 여기에 라이브러리 빌드에서 cmakelists.txt 파일입니다.

정적 라이브러리를 만들 때 해당 라이브러리에 대한 종속성은 라이브러리에 직접 연결되지 않습니다. 대신 실행 파일을 만들 때 모든 라이브러리 종속성 (직접 및 간접)이 해당 실행 파일에 직접 링크됩니다.

이것은 또한 대부분의 컴파일러가 정적 라이브러리를 처리하는 방식입니다. VS가 정적 라이브러리에 종속성을 연결하는 특별한 옵션을 제공하지만, 이는 예를 들어서 불가능합니다. 더러운 파일 해킹에 의지하지 않고 gcc. CMake는 지원되는 모든 생성기에서 사용할 수있는 기능 만 지원하므로 CMake는 VS 빌드에서도이 기능을 허용하지 않습니다.

  • 정적 라이브러리 (add_library(${libname} SHARED ...)) 대신 DLL을 사용

    는 이제 몇 가지 옵션이 있습니다. 정적 라이브러리는 기본적으로 함께 포장 된 오브젝트 파일의 묶음이지만 dll은 실행 파일과 거의 같습니다. 특히 모든 정적 라이브러리 종속성은 dll에 직접 연결됩니다. 여기서 단점은 일반적인 dll 난장판을 다루어야한다는 것입니다. 내보낼 함수와 dll 경계를 넘어가는 물건을 전달할 때의 일반적인 문제를 적용해야합니다.

  • 찾기 스크립트에서 모든 종속성을 검색하도록하십시오. 코드 중복 량이 최소화되는 방식으로 라이브러리의 종속성 처리를 재구성 할 수 있어야합니다. 단점은 타사 응용 프로그램을 구성하는 것이 더 어려워집니다 (특히 Windows의 경우). 이제는 라이브러리 자체뿐 아니라 모든 종속성을 찾을 필요가 있기 때문입니다.
  • exported targets을 사용하십시오.이 방법은 라이브러리가 최종 실행 파일과 동일한 시스템에 빌드 된 경우 가장 적합합니다. 라이브러리를 빌드 할 때 CMake는 해당 라이브러리를 사용하기위한 설정 파일을 자동으로 생성합니다. 따라서 응용 프로그램은 해당 스크립트가 포함되어 있는지 찾아야 만합니다. 단점은 수출 메커니즘이 CMake의 가장 직선적 인 기능이 아니기 때문에 시간을 투자하여 익숙해 져야한다는 것입니다.
  • 라이브러리 원본을 각 실행 파일에 직접 가져옵니다. 기본적으로 각 실행 파일은 라이브러리 소스 디렉토리에 add_subdirectory을 수행합니다. 각 실행 파일에 대한 종속성을 구성해야하며, 각 실행 파일에 대해 별도로 라이브러리를 빌드해야합니다. 당신은 아마 이것을하고 싶지 않을 것입니다.
+0

여기 나열되지 않은 옵션 중 하나는 라이브러리와의 종속성을 배포 한 경우에만 사용할 수 있습니까? 그들이 MyLib.lib와 같은 위치에있는 한, cmake는 그것을 찾을 수 있어야합니다. 이는 클라이언트가 DLL 또는 완벽하게 이식 가능한 실행 파일에 대한 자체 링크를 수행 할 수 있음을 의미합니다. 이 솔루션으로 인해 예상치 못한 문제가 발생할 가능성이 있습니까? 필자가 가장 염려하는 점은 클라이언트를 구축 할 때 사용한 것과 동일한 버전의 앱을 클라이언트가 사용하고 싶지 않기를 바란다는 것입니다. – OcularProgrammer

+0

@OcularProgrammer 이것은 기본적으로 옵션 # 2입니다 : 의존성을 해결할 수있는 find 스크립트를 작성할 수 있습니다. 라이브러리 버전을 혼합하는 것은 문제이지만 유감스럽게도 모든 형태의 바이너리 라이브러리 배포에 적용됩니다. Boost 유형을 인터페이스에 표시하면 라이브러리와 실행 파일이 모두 동일한 부스트 버전을 사용해야합니다. 그렇지 않으면 라이브러리 경계를 넘어 부스트 유형을 전달하는 것은 아마도 엉망이 될 것입니다. 다른 버전의 포함 된 사용은 대개 괜찮습니다.하지만 가능한 경우이를 피하기 위해 노력해야합니다. – ComicSansMS

+0

충고에 대한 환호. MyLibConfig.cmake는 라이브러리와 종속성을 디렉토리 구조에서 올바르게 가져 오기 위해 약간의 해킹이 필요했지만 모든 종속성을 가져 와서 적절한 lib 디렉토리로 옮길 때 멋진 휴대용 설치 패키지가되었습니다. 고맙습니다. – OcularProgrammer

관련 문제