Haruskah saya menambahkan sumber perpustakaan daripada menautkannya?

14

Saya relatif baru untuk C ++, jadi saya tidak yakin bagaimana saya harus menangani dependensi kecil (misalnya, bahasa scripting, atau Parser JSON / YAML / XML).

Haruskah saya membuat proyek terpisah dan menautkannya sebagai pustaka statis, atau apakah ada sisi buruk dari hanya menempatkan file .h / .cpp ke proyek utama saya?

Yang terakhir tampaknya jauh lebih mudah karena saya telah menghabiskan beberapa jam berurusan dengan perpustakaan yang tidak kompatibel (pengaturan kompiler berbeda ketika membangun perpustakaan), tetapi saya tidak ingin memulai belajar C ++ dengan cara yang salah.

Jika lebih baik menyimpannya sebagai pustaka yang terpisah, bagaimana cara terbaik agar flag kompilasi tetap sinkron agar file .lib / .a berhasil ditautkan ke aplikasi saya?

(Saya saat ini bekerja dengan MSVC 2015, tetapi tujuannya adalah untuk mengkompilasi di Mac OS X dan iOS menggunakan XCode / dentang, sehingga saya harus berurusan dengan setidaknya 3 jenis perpustakaan yang berbeda (Win x86, Mac x64, ARM) )

Michael Stum
sumber
5
Lihat ABIss dan mereka akan melihat Anda
Basilevs
1
Ingatlah bahwa beberapa perpustakaan dimaksudkan untuk digunakan dengan cara ini. The SQLite pola penggunaan yang disukai perpustakaan adalah untuk menjatuhkan sumber digabung dan file header ke dalam pohon sumber aplikasi C atau C ++ untuk dikompilasi ke dalam executable.
Mark Benningfield

Jawaban:

6

TLDR;

Haruskah Anda menambahkan sumbernya? YA
Haruskah X menambahkan sumber? TERGANTUNG

Inilah sebabnya ...

Kembali pada hari itu, waktu kompilasi adalah masalah proyek yang bahkan lebih kecil. Mengkompilasi sumber Anda dan tidak pernah khawatir tentang caching hasil kompiler jelas menarik bagi sebagian orang. Itu satu poin untuk perpustakaan yang tidak relevan dengan Anda.

Yang penting lainnya adalah versi. Apakah Anda benar-benar perlu versi setiap perpustakaan secara terpisah? Jalankan tes terhadap masing-masing? Mendistribusikannya di antara banyak anggota tim? Perpustakaan sangat bagus jika Anda melakukannya, dan nyaman untuk bergerak, tetapi sekali lagi, tampaknya Anda juga tidak peduli tentang hal ini.

Poin terakhir di sini adalah, ini merupakan overhead tambahan, dan menjatuhkan file sumber lebih mudah dalam kasus Anda, yang memberikan poin yang sangat kuat untuk menjatuhkan sumber daripada menggunakan perpustakaan. Seperti yang Anda perhatikan, setelah Anda membuat satu perubahan pengaturan kompiler, Anda harus mengejar semua dependensi sebaliknya.

Saya tahu semua ini dari pengalaman:

Untuk proyek Swift, saya pasti menggunakan frameworks (libraries) dan tautannya, karena sangat mudah untuk mengonfigurasi menggunakan Xcode. Saya juga sangat membutuhkan versi, tes, dan decoupling di sana, jadi itu sebabnya.

Untuk proyek-proyek Mono (C #), untuk Unity, saya mulai dengan pendekatan tergesa-gesa memecah proyek menjadi perpustakaan, mengkompilasi dan menguji masing-masing, yang hebat ... tapi begitu saya menjatuhkan perpustakaan ke Unity, segala macam masalah terjadi , dari versi peretasan yang digunakan Mono Unity, hingga perilaku yang kadang berbeda yang ditunjukkan kode ketika mengubah platform. Tidak memiliki IDE tunggal di sini untuk mengelola semua perpustakaan adalah rasa sakit yang nyata, jadi menempatkan semua sumber di dalam Unity adalah kemenangan besar bagi produktivitas.

Akhirnya, yang paling relevan bagi Anda, proyek game C ++ yang saya kerjakan. Mesin permainan, klien jaringan waktu nyata, klien jaringan HTTP, AI, dan toko kegigihan ditulis untuk permainan ini, hanya di sisi klien. Apa yang saya pilih? CLion + Libraries. Meskipun saya menggunakan perpustakaan, saya tidak merasa seperti itu. Semua sumber ada di proyek CLion IDE, dan dengan menyusun CMakeLists, saya dapat memicu semua build dan menautkannya dalam satu stroke.

Sebagai kesimpulan , saya akan mengatakan menggunakan perpustakaan adalah solusi masa depan-bukti, tetapi juga optimasi prematur jika tidak diperlukan. Sejauh yang saya bisa memastikan dari situasi Anda, beralih dari MSVC ke Xcode akan menyusahkan jika Anda akan memiliki beberapa target build. Jadi, cukup masukkan dan pertahankan isolasi sebanyak mungkin untuk saat ketika Anda mungkin perlu menggunakan perpustakaan.

PS: Saya mengalami dilema yang sama belakangan ini dengan buruh pelabuhan. Haruskah saya menulis? Haruskah saya menjalankan secara lokal? .. dll. Juga Elixir, karena memungkinkan Anda untuk membangun Aplikasi dalam aplikasi yang sama .. Haruskah saya melakukan itu? Atau pisahkan aplikasi ke dalam apa yang disebut layanan mikro? ... dll. Tidak ada peluru perak, selalu ukur dirimu, seperti YMMV.

Mazyod
sumber
2

Menautkan dengan perpustakaan C ++ membutuhkan banyak kesulitan, dan itu membutuhkan banyak pengetahuan dan upaya untuk melakukannya dengan benar. Ini bisa menakutkan bagi pelajar C ++.


Sering kali, penulis / pengelola perpustakaan C ++ tertentu memiliki pemikiran ini, dan akan merekomendasikan satu cara atau yang lain.

Dengan kata lain, jika penulis / pengelola bermaksud perpustakaan untuk dimasukkan oleh header (* .h dan .hpp saja), atau termasuk oleh sumber ( .h *, atau .c ), itu akan mengatakan dengan jelas dalam readme atau dokumentasi.


Perpustakaan yang dirancang dan dipelihara untuk menjadi lintas platform (dan kompatibel dengan beberapa vendor dan lingkungan kompiler C ++) akan sering memiliki sistem makefile atau sistem konfigurasi build (seperti CMake). Sistem ini digunakan untuk menghasilkan shim header yang menghaluskan perbedaan platform, dan untuk menghasilkan skrip yang akan memanggil kompilator dan tautan pada file sumber menggunakan opsi baris perintah yang tepat dan dalam urutan yang benar. Bergantung pada platform dan konfigurasi, sistem pembangunan ini dapat menyertakan atau mengecualikan header atau file sumber tertentu, atau mereka dapat mendefinisikan atau mendefinisikan simbol preprosesor tertentu.


Melawan rekomendasi penulis / pengelola dimungkinkan, tetapi itu selalu membutuhkan upaya porting yang luas. Jumlah pekerjaan yang diperlukan untuk upaya porting dapat dibandingkan dengan porting ke lingkungan C ++ yang berbeda.


Karena Visual C ++ menggunakan sistem build sendiri berdasarkan pada file deskripsi proyek (sebagian berbasis XML), itu sangat berbeda dengan sistem build berbasis scripting yang digunakan di Linux. Pendekatan yang digunakan oleh CMake adalah CMake untuk mengambil pengaturan konfigurasi, dan kemudian memancarkan seluruh struktur proyek Visual C ++, dengan opsi konfigurasi yang dimasukkan ke file * .vcxproj.

Jika masalah muncul selama penautan C ++ dengan Visual C ++, pengaturan build di file * .vcxproj dapat dimodifikasi menggunakan Visual Studio GUI (menggunakan dialog halaman properti proyeknya). Ini mengasumsikan Anda memahami secara menyeluruh makna dan konsekuensi dari selusin pengaturan kompilasi C ++ yang penting.

Sekarang sampai pada bagian paling bodoh menggunakan Visual C ++: jika Anda menggunakan selusin pustaka pihak ketiga yang berbeda, mengubah pengaturan build untuk semuanya berarti masuk ke setiap file * .vcxproj, dan mengulangi perubahan yang sama pada GUI untuk selusin waktu. Sebuah kerumitan, tetapi itu bisa dilakukan, jika Anda tahu cara melakukannya dengan benar.

Kebanyakan pelajar Visual C ++ mempelajari pengaturan ini dengan cara yang sulit, dengan mengamati kesalahan penyusun dan penghubung Visual C ++, yang diidentifikasi oleh kode kesalahan mereka. Sebagai contoh, seseorang dapat mencari LNK2005, dengan makna dangkal "Simbol simbol didefinisikan lebih dari sekali," tetapi dengan pemahaman bahwa definisi duplikat tidak muncul dari kesalahan pemrograman yang ceroboh, alih-alih itu bisa terjadi karena beberapa konflik atau kesalahan penerapan opsi kompilasi dan penautan.


Untuk memberikan jawaban yang lebih spesifik dan berguna untuk situasi Anda, orang perlu mengetahui nama perpustakaan yang ingin Anda gunakan, serta kesalahan penautan atau kesulitan lain yang Anda temui. Anda dapat menemukan jawaban yang ada untuk pertanyaan-pertanyaan itu di papan diskusi perpustakaan masing-masing. Pertanyaan-pertanyaan ini cenderung ditandai dengan "masalah penautan", "windows", dan "visual C ++".

Panduan pemula-ke-ahli tentang masalah ini dimungkinkan, tetapi akan lebih spesifik untuk proyek. Preferensi yang berbeda yang dipilih oleh proyek yang berbeda akan membutuhkan penulisan ulang panduan yang lengkap.

rwong
sumber
Jika Anda menggunakan CMake untuk memancarkan .vcxproj, daripada memodifikasi .vcxproj, Anda dapat memodifikasi konfigurasi CMake
Caleth
1

Saya akan mengatakan ya, asalkan lebih mudah. Ada cukup banyak manfaat:

  1. Ini akan menghasilkan kode yang lebih cepat dan lebih baik, terutama jika Anda mengaktifkan Link Time Optimization.

  2. IDE Anda akan lebih menyukainya, mis. Itu akan (semoga) memungkinkan Anda untuk beralih ke implementasi (.cpp) kode perpustakaan, daripada hanya antarmuka (.h), yang sangat berguna ketika bekerja dengan kode yang tidak terdokumentasi dengan baik (mis. kebanyakan kode).

  3. Ini sering memungkinkan Anda untuk menambahkan dependensi sebagai submitule git, yang merupakan cara yang sedikit meretas tetapi sebenarnya cukup bagus untuk memiliki dependensi (untuk C ++, yang tidak memiliki sistem build waras). Itu membuatnya sangat mudah untuk memperbarui perpustakaan dan menguji berbagai versi.

  4. Anda tidak perlu khawatir tentang ketergantungan yang dikompilasi dengan MSVC ++ 2013, saat Anda menggunakan 2017 misalnya. Atau dibagikan vs MSVCRT statis.

  5. Anda dapat dengan mudah membangun dalam mode debug dan masuk ke perpustakaan.

Satu-satunya alasan saya pikir Anda tidak ingin melakukan ini, adalah jika perpustakaannya besar dan memiliki sistem pembangunan yang rumit yang tidak ingin Anda tiru di dalam milik Anda, misalnya Boost atau LLVM. Tetapi untuk perpustakaan sederhana tidak ada kerugian sebenarnya.

Sebagai contoh, saya menggunakan libusb di beberapa proyek, dan saya perlu mendukung Windows. libusb menggunakan autotool yang merupakan lelucon dari sistem build dan tidak benar-benar berfungsi pada Windows. Mereka memang menyediakan binari yang telah dikompilasi tetapi mereka dibangun dengan MSVC ++ 2013 dan tidak akan berfungsi pada 2017. Solusi termudah sejauh ini adalah menambahkan semua file .c dan .h yang relevan ke proyek saya.

Timmmm
sumber
2
1) benarkah? Pustaka statis hanyalah kumpulan file objek, seperti jika Anda baru saja mengompilasinya.
Baldrickk
Anda dapat membuat arsip .ofile yang telah dikompilasi -fltotetapi itu bukan perpustakaan statis - untuk Dentang mereka adalah file bitcode LLVM. Dan itu jelas tidak akan berhasil jika Anda menggunakan perpustakaan statis yang disediakan orang lain.
Timmmm
ok, mari perbarui diskusi ini - Saya menantikan untuk belajar beberapa hal lagi :)
Baldrickk