Programming

CMake가 동일한 라이브러리의 정적 및 공유 버전을 모두 빌드 할 수 있습니까?

procodes 2020. 7. 7. 08:10
반응형

CMake가 동일한 라이브러리의 정적 및 공유 버전을 모두 빌드 할 수 있습니까?


동일한 소스는 정적 및 공유 버전을 모두 원합니다. 쉬운가요?


예, 적당히 쉽습니다. 두 개의 "add_library"명령을 사용하십시오.

add_library(MyLib SHARED source1.c source2.c)
add_library(MyLibStatic STATIC source1.c source2.c)

소스 파일이 많은 경우에도 소스 목록을 cmake 변수에 배치하면 여전히 쉽습니다.

Windows에서는 공유 및 정적 파일에 ".lib"파일이 있으므로 각 라이브러리에 다른 이름을 지정해야합니다. 그러나 Linux 및 Mac에서는 두 라이브러리에 동일한 이름 (예 : libMyLib.alibMyLib.so) 을 지정할 수도 있습니다 .

set_target_properties(MyLibStatic PROPERTIES OUTPUT_NAME MyLib)

그러나 정적 및 동적 버전의 라이브러리에 동일한 이름을 지정하지 않는 것이 좋습니다. 라이브러리에 링크하는 도구의 컴파일 라인에서 정적 링크와 동적 링크를 더 쉽게 선택할 수 있기 때문에 다른 이름을 사용하는 것이 좋습니다. 일반적으로 libMyLib.so(공유) 및 libMyLib_static.a(정적) 같은 이름을 선택합니다 . (이것은 리눅스에서 이름이 될 것입니다.)


CMake 버전 2.8.8부터 "개체 라이브러리" 사용 하여 개체 파일의 중복 컴파일을 피할 수 있습니다 . 두 개의 소스 파일이있는 Christopher Bruns의 라이브러리 예제 사용 :

# list of source files
set(libsrc source1.c source2.c)

# this is the "object library" target: compiles the sources only once
add_library(objlib OBJECT ${libsrc})

# shared libraries need PIC
set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)

# shared and static libraries built from the same object files
add_library(MyLib_shared SHARED $<TARGET_OBJECTS:objlib>)
add_library(MyLib_static STATIC $<TARGET_OBJECTS:objlib>)

로부터 CMake 워드 프로세서 :

오브젝트 라이브러리는 소스 파일을 컴파일하지만 오브젝트 파일을 라이브러리에 아카이브하거나 링크하지 않습니다. 대신 다른 대상 은 양식의 표현식을 소스로 사용하여 오브젝트를 참조 add_library()하거나 add_executable()참조 할 수 있습니다 $<TARGET_OBJECTS:objlib>. 여기서 objlib는 오브젝트 라이브러리 이름입니다.

간단히 add_library(objlib OBJECT ${libsrc})말해이 명령은 CMake에게 소스 파일을 *.o객체 파일 로 컴파일하도록 지시 합니다. *.o그런 다음 파일 콜렉션을 동일한 오브젝트 파일 세트 에서 공유 및 정적 라이브러리를 빌드하는 적절한 라이브러리 작성 명령을 호출 $<TARGET_OBJECT:objlib>하는 두 add_library(...)명령 에서 참조됩니다 . 소스 파일이 많은 경우 파일을 컴파일하는 데 시간이 오래 걸릴 수 있습니다. 객체 라이브러리를 사용하면 한 번만 컴파일 할 수 있습니다.*.o

당신이 지불하는 가격은 공유 라이브러리가 이것을 필요로하기 때문에 객체 파일이 위치 독립적 코드로 작성되어야한다는 것입니다 (정적 라이브러리는 신경 쓰지 않습니다). 위치 독립적 인 코드는 효율성이 떨어질 수 있으므로 성능을 극대화하려면 정적 라이브러리를 사용하십시오. 또한 정적으로 링크 된 실행 파일을 배포하는 것이 더 쉽습니다.


일반적으로 목적을 위해 ADD_LIBRARY 호출을 복제 할 필요는 없습니다. 그냥 활용하십시오

$> man cmake | grep -A6 '^ *BUILD_SHARED_LIBS$' 
   BUILD_SHARED_LIBS
          Global flag to cause add_library to create shared libraries if on.

          If present and true, this will cause all libraries to be built shared unless the library was
          explicitly added as a static library.  This variable is often added to projects as an OPTION
          so  that each user of a project can decide if they want to build the project using shared or
          static libraries.

-DBUILD_SHARED_LIBS : BOOL = ON을 사용하고 다른 하나는 OFF를 사용하여 소스 외부 디렉토리에서 먼저 빌드하는 동안


실제로 가능합니다. @Christopher Bruns가 그의 답변에서 말했듯이 라이브러리의 두 가지 버전을 추가해야합니다.

set(libsrc source1.c source2.c source3.c)
add_library(mylib-static STATIC ${libsrc})
add_library(mylib-shared SHARED ${libsrc})

그런 다음 여기설명 된대로 두 대상 모두 동일한 출력 이름을 사용하고 서로의 파일을 덮어 쓰지 않도록 지정해야합니다.

SET_TARGET_PROPERTIES(mylib-static PROPERTIES OUTPUT_NAME mylib CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(mylib-shared PROPERTIES OUTPUT_NAME mylib CLEAN_DIRECT_OUTPUT 1)

이 방법으로 libmylib.a 및 libmylib.so (Linux) 또는 mylib.lib 및 mylib.dll (Windows)을 모두 얻을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/2152077/is-it-possible-to-get-cmake-to-build-both-a-static-and-shared-version-of-the-sam

반응형