大規模的C++項目是如何保證各個解決方案以及下面各工程的順序編譯?
一個大型的項目必然包含多個解決方案(.sln)及工程(.vcxproj),那麼是如何組織他們按既定的順序生成多個動態庫(因為工程之間有相互依賴,編譯上肯定有先後順序)。請各位大神指點迷津。
CMake。只要填寫了正確的Dependency就可以了。
——————————————————————————
BTW.
按道理Linker應該在所有包含進來的二進位編譯單元文件中尋找符號進行鏈接,但是GCC的Linker比較缺心眼,只能對Obj按照一個順序來掃描符號完成鏈接。如果A引用B但是A又是在B之前被掃描的那就會遇到unresolved symbols錯誤。
所以在binary unit中,需要對庫做一個排序。如果庫A和B交叉引用了,那麼只能按照ABA的順序來鏈接,或者把所有的.o文件都弄到一個archive中。
c++ - Why does the order in which libraries are linked sometimes cause errors in GCC?c - Why does the order of -l option in gcc matter?如果一個sln裡面的vcxproj依賴了別的sln的vcxproj,我會把那些工程通過Add Existing Project加進來,然後引用它們。
這樣的好處有兩個:
1、完美解決了依賴順序的問題。2、就算你用msbuild同時編譯這些sln,被依賴的那些、同時出現在幾個sln的vcxproj,也不會被重複編譯。3、使用vcxproj的工程屬性來引用別的vcxproj,他們編譯出來的lib還會被自動鏈接,然後dll和exe反正都是輸出(通常來講,大家都會改這個目錄)在同一個目錄的,編譯完可以直接運行。就像這樣:https://github.com/vczh-libraries/Release/blob/master/Tutorial/GacUI_Xml/GacUI_Xml.sln推薦使用CMake與Lua premake。
使用構建工具/系統
我在玩具項目中使用過make
在嚴肅項目中使用過scons、blade僅就個人感受,簡單點評一下:
make之於構建工具,猶如javascript之於瀏覽器、彙編之於編程語言,抽象程度非常之低,僅僅是自動化了「手敲編譯命令「。scons更像是構建工具中的C語言,對常見的構建任務、依賴管理、源代碼監控都有著恰到好處的抽象,屏蔽了一些無必要的瑣碎的工作。與此同時,介面足夠靈活,高度可定製,能夠進行複雜的深度的二次開發。
我司的項目符合「大規模C++項目這一標準」,過去就是使用scons編譯的,針對自身場景進行了深度的二次開發。每個模塊描述好自己的依賴關係,任一模塊代碼變動,該模塊及其依賴都自動觸發重新編譯。
blade是構建工具中的DSL,底層生成scons腳本完成編譯任務,對編譯、測試的典型場景設計了一套抽象程度更高更加human-friendly的DSL。
較scons的明顯優點:內置實現了靜態庫依賴管理(效果同動態庫的依賴管理,每個模塊只負責指定自己的依賴,無需指定依賴的依賴)。較scons的致命缺點:不可二次開發,這導致超出DSL描述範圍的任務都無法完成。總結:
make:不推薦使用scons:推薦blade:推薦。如果需要進行二次開發,只能去github提issue了PS:
@空明流轉提到的編譯庫循環依賴問題,我認為是當初linker開了一個不好的口子,導致後續一系列的奇技淫巧和醜陋的補丁。更好的解決辦法是從最底層的linker就禁止這種情況的出現,強制報錯,反推用戶修改。出現循環依賴問題,往往是庫的粒度過粗,邊界沒有定義清楚,應該強制用戶對庫進行更細粒度的拆分,以避免循環依賴情況的發生。說不定,因為linker不妥協這一微小的蝴蝶效應,能夠更早地在c/c++的生態中孕育出類似於PyPi/npm一樣的集中式地包管理系統。
- Make - GNU Project
- SCons: A software construction tool
- GitHub - chen3feng/typhoon-blade: Building system of typhoon cloud computing platform of tencent, support C/C++/protobuf/thrift/lex/yacc/swig.
多個make順序搞不就行了
vs的話更簡單,右鍵設置依賴不就行了可以試試 xmake 。。比起直接寫makefile 以及 autoconf 簡單多了。。而且跨平台。。也是基於Lua,靈活方便
xmake是完全直接編譯,不依賴makefile,當且也可以生成工程文件,主要以插件方式提供。。
target("console")
set_kind("binary")
add_files("src/*.c")
其他的我不知道。chromium這麼大的工程是通過gyp這種格式(就是json)的文件來管理的。類似這種:
// chrome_child.gypi
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
targets: [
{
target_name: child,
type: static_library,
variables: { enable_wexit_time_destructors: 1, },
dependencies: [
../base/base.gyp:base,
../content/content.gyp:content_child,
],
include_dirs: [
..,
],
sources: [
child/pdf_child_init.cc,
child/pdf_child_init.h,
],
},
],
}
然後使用depot_tools之類的玩意,生成輪子哥說的vcxproj工程文件。
編譯器會自己解決。現在編譯技術越來越先進了,用機器學習的都有很多文章了。
Linux下,都是有Makefile規定的
Makefile可以檢查依賴,然後保證編譯鏈接最終完成推薦閱讀:
※有哪些看似簡單其實非常精妙的代碼?
※C++IO標準庫 能否非入侵的修改<< >>操作符的行為?
※若要向C++之父 Bjarne Stroustrup 請教10個技術Topics,有什麼好的建議么?
※是否有去除c++多餘頭文件的工具?
※C++ 的 sizeof 是怎麼實現的?