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.a
및 libMyLib.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)을 모두 얻을 수 있습니다.
'Programming' 카테고리의 다른 글
tr과 gsub의 차이점은 무엇입니까? (0) | 2020.07.07 |
---|---|
C ++에서 iPhone을 프로그래밍 할 수 있습니까? (0) | 2020.07.07 |
smtp가 명령 줄에서 작동하는지 확인하는 방법 (Linux) (0) | 2020.07.07 |
BCrypt는 C #에서 사용하기에 적합한 해싱 알고리즘입니까? (0) | 2020.07.07 |
숫자가 정규 표현식의 소수인지 확인하는 방법은 무엇입니까? (0) | 2020.07.07 |