Saya sedang mengerjakan proyek kecil untuk memahami rantai kompiler dan tautan dengan lebih baik.

Misalkan saya memiliki perpustakaan libfoo.a dan libbar.a. Saya ingin membuat perpustakaan libmy.a, yang bertindak seperti pembungkus atau API tingkat atas untuk kedua perpustakaan. Targetnya adalah, hanya libmy.a yang diperlukan untuk membangun executable, yang menggunakan fungsi pembungkus yang saya tetapkan. Saya membuat proyek cmake dan mengatur perpustakaan

cmake_minimum_required(VERSION 3.14)
project(Wrapper)

set(CMAKE_CXX_STANDARD 11)


add_library(my STATIC ${SOME_SRC_FILES})

#set up the lib/inc paths and libs to link
target_include_directories(my PUBLIC /path/to/Foo/inc/ /path/to/Bar/inc/)
target_link_directories(my PUBLIC /path/to/Foo/lib/ /path/to/Bar/lib)
target_link_libraries(my PUBLIC foo bar)

Itu berfungsi dengan baik dan tidak ada masalah dalam kompilasi. Namun, jika saya mencoba mereferensikan objek dari proyek eksternal, itu memberi tahu saya, bahwa saya memiliki referensi yang tidak terdefinisi ke fungsi di libfoo.a dan libbar.a. Sejauh yang saya pahami masalahnya, tautan hanya membuat deklarasi di libmy.a, tanpa menyertakan definisinya dari perpustakaan eksternal. Saya memeriksa ini dengan membuka libmy.a dengan perintah nm libmy.a, di mana fungsi yang digunakan dari perpustakaan eksternal dideklarasikan, tetapi tidak ditentukan.

Saya menemukan satu solusi yang menggunakan ar untuk menggabungkan beberapa file perpustakaan. Namun saya ingin menghindari metode seperti itu, karena jika itu bukan satu perpustakaan, tetapi sekelompok, katakanlah 10 perpustakaan, tidak cocok untuk mencari setiap perpustakaan untuk definisi dan menyalinnya ke libmy.a. Hanya membuang semua perpustakaan bersama-sama juga bukan solusi, karena file akan menjadi terlalu besar.

Apakah penting dan perlu diperhatikan, bahwa salah satu paket library ini adalah CUDA?

Saya yakin ada solusi, tetapi saya tidak dapat menemukannya. Bantuan apa pun akan dihargai

0
JulCode 19 September 2019, 20:52

1 menjawab

Jawaban Terbaik

Targetnya adalah, hanya libmy.a yang diperlukan untuk membangun sebuah executable

Ini sudah merupakan tujuan yang tidak biasa untuk perpustakaan statis.

Pustaka statis biasanya hanya berisi kode objek yang dibuat dari kode sumber untuk pustaka itu. Pengguna pustaka tersebut juga harus menautkan ke pustaka yang diperlukan pustaka Anda, karena definisi belum disalin ke pustaka Anda saat dibuat.

Alat seperti ar dapat digunakan untuk menggabungkan beberapa perpustakaan statis, karena mereka hanya arsip kode objek. Alat ini tidak dapat memprediksi kode objek mana yang akan digunakan pengguna akhir, jadi alat ini akan menggabungkan seluruh pustaka. Jika tidak, pengguna akhir mungkin mencari definisi yang Anda tinggalkan dan kemudian perlu menautkan dalam salinan ke-2 dari lib ketergantungan.

Jika Anda ingin menyediakan perpustakaan yang memiliki semua yang dibutuhkan pengguna akhir, mengurangi apa yang sebenarnya digunakan pembungkus Anda, Anda dapat membangun perpustakaan bersama. Pustaka bersama dianggap dapat dieksekusi, sehingga kompiler mengetahui bahwa kode objek yang tidak direferensikan tidak akan digunakan, dan tidak akan disertakan dalam pustaka bersama.

Anda dapat memaksa seluruh pustaka statis untuk disertakan dalam pustaka bersama.
Di GCC, Anda dapat menggunakan argumen tautan: --whole-archive untuk memastikan bahwa semua kode objek dari pustaka berikut disertakan.
Di MSVC, Anda dapat menggunakan argumen /WHOLEARCHIVE:<library file name> untuk melakukan hal yang sama.

1
Romen 20 September 2019, 12:57