簡體   English   中英

捆綁 static C++ 庫時如何防止 CMake 雙重編譯源?

[英]How to prevent CMake from double compiling sources when bundling static C++ libraries?

我正在嘗試使用 CMake 構建一個 static 庫libbar libbar應該包含libfoo ,即子目錄目標libfoo中的所有 object 文件也應該出現在libbar中。 最簡單的目錄樹如下:

bar
├── bar.cpp
├── CMakeLists.txt
└── foo
    ├── CMakeLists.txt
    └── foo.cpp

這是foo/CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
project(foo)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_library(foo)
target_sources(foo PUBLIC foo.cpp)

這是頂級CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(bar)

add_library(bar)
add_subdirectory(foo)
target_sources(bar PUBLIC bar.cpp)
target_link_libraries(bar PRIVATE foo)

bar/我執行以下操作:

cmake . -Bbuild
cd build
cmake --build .

我得到

Scanning dependencies of target foo
[ 20%] Building CXX object foo/CMakeFiles/foo.dir/foo.cpp.o
[ 40%] Linking CXX static library libfoo.a
[ 40%] Built target foo
Scanning dependencies of target bar
[ 60%] Building CXX object CMakeFiles/bar.dir/bar.cpp.o
[ 80%] Building CXX object CMakeFiles/bar.dir/foo/foo.cpp.o
[100%] Linking CXX static library libbar.a
[100%] Built target bar

如您所見,文件foo.cpp被編譯了兩次,我正試圖擺脫這種行為。 順便說一句,這個方法給了我一個正確的結果:

$ ar t libbar.a 
bar.cpp.o
foo.cpp.o

如果我在foo/CMakeLists.txt中將 PUBLIC 更改為 PRIVATE ,則構建日志如下:

Scanning dependencies of target foo
[ 25%] Building CXX object foo/CMakeFiles/foo.dir/foo.cpp.o
[ 50%] Linking CXX static library libfoo.a
[ 50%] Built target foo
Scanning dependencies of target bar
[ 75%] Building CXX object CMakeFiles/bar.dir/bar.cpp.o
[100%] Linking CXX static library libbar.a
[100%] Built target bar

但 foo.cpp.o 沒有進入libbar

$ ar t libbar.a 
bar.cpp.o

在沒有雙重編譯的情況下構建包含libfoolibbar的正確方法是什么?

target_sources(foo PUBLIC foo.cpp)

此行強制鏈接到foo的目標在其源中包含foo.cpp

在沒有雙重編譯的情況下構建包含 libfoo 的 libbar 的正確方法是什么?

你已經明確要求這個,所以只是......不要:

target_sources(foo PRIVATE foo.cpp)
  • PUBLIC的意思是“適用於自己和被鏈接者”。
  • PRIVATE的意思是“適用於自己”
  • INTERFACE的意思是“僅適用於被鏈接者”

如果您真的希望foo.o在兩個檔案中(這是可疑的),那么您可以使用libbarlibfoo鏈接到的OBJECT庫。

add_library(foo_objs OBJECT foo.cpp)

# later ...
target_link_libraries(foo PRIVATE foo_objs)
# ...
target_link_libraries(bar PRIVATE foo_objs)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM