項目經(jīng)驗分享|Curve社區(qū) 陳欣怡:勇敢小白與死線戰(zhàn)士

開源之夏個人專訪與項目經(jīng)驗分享持續(xù)開放中,歡迎已從開源之夏畢業(yè)或正在參與開源之夏活動的學(xué)生、導(dǎo)師一同加入專訪行動,掃描文末二維碼填寫專訪問卷,與大家分享你眼中的開源之夏!
本期項目經(jīng)驗分享來自Curve社區(qū)中選學(xué)生——陳欣怡,在開源之夏2023中承擔的項目是支持編譯指定的cc_library。

#?關(guān)于?Curve?社區(qū)
Curve是網(wǎng)易自主設(shè)計研發(fā)的高性能、易運維、云原生的分布式存儲系統(tǒng),目前提供塊(CurveBS)和文件(CurveFS)兩種存儲方式。CurveBS支持快照克隆和恢復(fù),支持QEMU虛擬機和物理機NBD設(shè)備兩種掛載方式。CurveFS基于Fuse支持POSIX文件系統(tǒng)接口。
官網(wǎng):https://www.opencurve.io/
# 項目基本信息
項目名稱:支持編譯指定的cc_library
項目導(dǎo)師:Wine93
項目描述:Curve目前的Makefile只支持 cc_binary 的編譯。
curve$ make
## list
Usage:
? ?make list stor=bs/fs
Examples:
? ?make list stor=bs
## build
Usage:
? ?make build stor=bs/fs only=TARGET dep=0/1 release=0/1 os=OS
Examples:
? ?make build stor=bs only=//src/chunkserver:chunkserver
? ?make build stor=bs only=src/* dep=0
? ?make build stor=fs only=test/* os=debian9
? ?make build stor=fs release=1
希望開發(fā)者對 Makefile 進行修改,支持編譯指定的 cc_library。
參與者需要熟悉基本的 shell 腳本編程,熟悉 bazel 編譯,熟悉 Makefile。
項目鏈接:https://summer-ospp.ac.cn/org/prodetail/232990062
#?項目開發(fā)經(jīng)驗分享
項目實現(xiàn)總思路
第一步:了解前置知識,閱讀并理解原倉庫相關(guān)代碼
第二步:在image和物理機中分別實現(xiàn)cc_library的編譯
第三步:相關(guān)makefile修改,添加編譯選項和注釋
第四步:pr修改-格式修改、debian版本的編譯參數(shù)傳遞等
項目實現(xiàn)細節(jié)
源碼理解
get_options():解析命令行參數(shù)和選項
list_target():列出目標編譯對象
build_target():構(gòu)建目標,并建立target和result的對應(yīng)
具體源碼解讀不在此贅述。
實現(xiàn)cc_library的編譯
實現(xiàn)list_target函數(shù)
實現(xiàn)思路:該函數(shù)目標列出所有編譯對象,使用bazel query實現(xiàn)。目標是找出所有包括cc_library編譯對象的主目錄即為成功。
首先,對于已有代碼,也即cc_binary的實現(xiàn)做分析。
參考社區(qū)中“Curve源碼解讀”文檔輔助架構(gòu)理解后,理解bs和fs文件所在,添加代碼如下
? ? ? ? ? ? ? ?print_title " SOURCE TARGETS "
? ? ? ?bazel query 'kind("cc_binary", //src/...)'
? ? ? ?bazel query 'kind("cc_binary", //tools/...)'
? ? ? ?bazel query 'kind("cc_binary", //nebd/src/...)'
? ? ? ?bazel query 'kind("cc_binary", //nbd/src/...)'
? ? ? ?bazel query 'kind("cc_library", //include/...)'
? ? ? ?bazel query 'kind("cc_library", //src/...)'
? ? ? ?bazel query 'kind("cc_library", //nebd/src/...)'
? ? ? ?bazel query 'kind("cc_library", //nbd/src/...)'
? ? ? ?print_title " TEST TARGETS "
? ? ? ?bazel query 'kind("cc_(test|binary)", //test/...)'
? ? ? ?bazel query 'kind("cc_(test|binary)", //nebd/test/...)'
? ? ? ?bazel query 'kind("cc_(test|binary)", //nbd/test/...)'
? ? ? ?bazel query 'kind("cc_library", //test/...)'
? ? ? ?bazel query 'kind("cc_library", //nebd/test/...)'
? ? ? ?bazel query 'kind("cc_library", //nbd/test/...)'
? ?elif [ "$g_stor" == "fs" ]; then
? ? ? ?print_title "SOURCE TARGETS"
? ? ? ?bazel query 'kind("cc_binary", //curvefs/src/...)'
? ? ? ?bazel query 'kind("cc_library", //curvefs/src/...)'
? ? ? ?print_title " TEST TARGETS "
? ? ? ?bazel query 'kind("cc_(test|binary)", //curvefs/test/...)'
? ? ? ?bazel query 'kind("cc_library", //curvefs/test/...)'
? ?fi
實現(xiàn)build_target
實現(xiàn)思路:同上,使用bazel?query實現(xiàn)cc_library的編譯項的掃描。
# test
# PRINT TO CHECK
? ?bazel query 'kind("cc_(test|binary|library)", //... -//curvefs/...)'
? ?bazel query 'kind("cc_(test|binary|library)", //... -//curvefs/...)' | grep -E "$g_target"
? ?for target in "${target_array[@]}"
? ?do
? ? ? ?echo "$target"
? ?done
? ?exit
target_array=($(bazel query 'kind("cc_(test|binary|library)", //... -//curvefs/...)' | grep -E "$g_target"))
target_array=($(bazel query 'kind("cc_(test|binary|library)", //curvefs/...)' | grep -E "$g_target"))
makefile修改
在之前開發(fā)的過程中,我遇到了失敗編譯項目的情況,因此在makefile中添加了相關(guān)注釋,幫助之后的新手開源者入門Curve。
build curvebs/ build curvefs: 需要先編譯依賴項,在編譯Curve項目。即需要先進行make dep,在進行make build?;蛘呤褂胢ake build dep=1。
make playground: Curve社區(qū)提供了docker容器,省去開發(fā)者配置環(huán)境的困擾。
## build curvebs
? ?make build stor=bs dep=1
? ?make dep stor=bs && make build stor=bs
## build curvefs
? ?make build stor=fs dep=1
? ?make dep stor=fs && make build stor=fs
## dep
## configure dependency(before build)
? ?Usage:
? ? ? ?make dep stor=bs/fs
? ?Examples:
? ? ? ?make dep stor=bs
? ?
## playground
## create/run a container, changes outside will be mapped into the container
? ?Usage/Example:
? ? ? ?make playground
實現(xiàn)debian版本的參數(shù)傳遞
實現(xiàn)思路:參數(shù)傳遞,解析參數(shù),變量更改
parse_cfg() {
? ?local args=`getopt -o v: --long version: -n "playground.sh" -- "$@"`
? ?eval set -- "${args}"
? ?while true
? ?do
? ? ? ?case "$1" in
? ? ? ? ? ?-v|--version)
? ? ? ? ? ? ? ?g_container_image="$2"
? ? ? ? ? ? ? ?shift 2
? ? ? ? ? ? ? ?;;
? ? ? ? ? ?--)
? ? ? ? ? ? ? ?shift
? ? ? ? ? ? ? ?break
? ? ? ? ? ? ? ?;;
? ? ? ? ? ?*)
? ? ? ? ? ? ? ?exit 1
? ? ? ? ? ? ? ?;;
? ? ? ?esac
? ?done
}
項目結(jié)果呈現(xiàn)
運行?make ci-build stor=bs only=//src/chunkserver/datastore:chunkserver_datastore

運行 make ci-build stor=fs only=//curvefs/src/metaserver:curvefs_metaserver

遇到的問題以及解決方案
虛擬機/Docker容器聯(lián)網(wǎng)問題
在docker中運行make ci-build stor=bs,然后發(fā)現(xiàn)容器中沒有聯(lián)網(wǎng)
Vmware Workstation Pro17 ubuntu20.04配置方法
查看主機客戶端(比如clash),在general中打開allow LAN
vmware workstation 17 pro 網(wǎng)絡(luò)適配器NAT模式
在主機終端上執(zhí)行ipconfig查看VMnet8的ipv4地址,如192.168.xx.xx
記錄下clash中https對應(yīng)的端口號,如7890
在虛擬機終端中執(zhí)行export https_proxy=192.168.xx.xx:7890
執(zhí)行echo $https_proxy查看是否設(shè)置成功
執(zhí)行curl -v https://www.google.com
提醒:每個終端都要配置一遍,重啟失效
playground重置
bazel clean
make build stor=fs dep=1
cat .obm.cfg
## eixt docker
docker rm -f curve-build-playground-master
vim .obm.cfg
## change debian9 to debian11, try to recompiler in the docker
make playground
make ci-build stor=fs dep=1
后續(xù)工作安排
在參加ospp后,我也在持續(xù)關(guān)注Curve社區(qū)的開發(fā)者活動,會繼續(xù)參加Curve社區(qū)的建設(shè)。
以及將在后期完成由rust語言編寫的容器管理項目:https://github.com/quas-modo/obm。
#?參與過程
回想這段第一次參與開源社區(qū)活動的經(jīng)歷,我想我會用這樣兩個詞來概括:勇敢小白與死線戰(zhàn)士。
故事開始在今年的四五月份,好友提起了開源之夏這項活動,豐厚的獎金、開源社區(qū)的參與經(jīng)歷、工業(yè)級大型項目的接觸經(jīng)歷等等都深深地吸引著我們。雖然一早就決定要申請試試,但由于當時繁重的課業(yè),加上讓人沒有頭緒的琳瑯滿目的社區(qū)和項目,我們紛紛犯了拖延癥,一直到接近提交項目申請尾聲的時候。
這是死線戰(zhàn)士的第一次斗爭。
考慮到編碼水平,我主要在Basic項目中尋找,而根據(jù)個人的技術(shù)棧和興趣,我選擇了java、c++、compile、machine learning作為主要的尋找對象。但當時開始聯(lián)系導(dǎo)師得太晚,這才意識到學(xué)長在經(jīng)驗分享中的“盡早聯(lián)系”“盡早開始了解”的含義,很多學(xué)生會在項目公示之后就尋找自己感興趣的項目并聯(lián)系導(dǎo)師,了解項目并進行社區(qū)的一些good issue的嘗試,而導(dǎo)師也會在此過程中確定人選。
但我并不想就此放棄機會,因此我還是聯(lián)系了感興趣的項目導(dǎo)師。好在得到Curve社區(qū)的wine93老師的肯定答復(fù),我快馬加鞭地了解社區(qū)背景、項目背景、技術(shù)棧,在三天之內(nèi)和老師交流初步想法并撰寫提交了項目計劃書。這個過程其實是比較驚險的,說實話,我對于項目要求的bazel、shell腳本撰寫并不很熟悉,對于項目的具體目的也是一頭霧水,但我仔細閱讀相關(guān)文檔、查閱資料,理解源碼意思,和導(dǎo)師交流初步想法以及確認初步想法的正確后,完成了一份較為詳盡的項目申請書,也幫助我最終中選了Curve社區(qū)的實現(xiàn)指定cc_library編譯的任務(wù)。
我勇敢地跨出了第一步,并盡可能地把握住機會。但當死線戰(zhàn)士并不是個好的習慣,如果我沒有收到wine93老師的回復(fù),那我可能就喪失了這一寶貴的鍛煉機會。
之后的六月,進入了期末周和等待項目入選學(xué)生公示的階段。
而七月和八月,由于個人精力分配出現(xiàn)的問題,支教、比賽、交流的事情接踵而來,我并沒有做到原先預(yù)期的多線程開發(fā),而是拖慢了整體項目推進的進度,我對此真的感到抱歉,在此期間我主要了解了docker、云原生、Curve社區(qū)的一些相關(guān)知識。普通人大多數(shù)時候,只能踏踏實實地做好一件事,如果再有機會參與開源之夏,我將保證自己在暑假留有更充足的精力進行開發(fā)。
真正上手開始編碼,則是到了九月初。
這是死線戰(zhàn)士的第二次斗爭。
復(fù)雜的環(huán)境、大型項目文件、虛擬機的網(wǎng)絡(luò)環(huán)境、不時出現(xiàn)的報錯問題等等都讓我有些焦慮、不安,懷疑自己真能按時提交pr并完成項目嗎?疑慮和猶疑向來不能解決問題。我知道我面對的是一個相對簡單初級的項目,而我所剩的時間絕對足夠完成這個項目。帶著這樣的信念,我選擇了沉下心來解決問題、編寫代碼。遇到問題時,我會先選擇google和gpt解決我的問題,但是遇到一兩天都沒有頭緒的問題,我還是會叨擾我的mentor。在此很感謝wine93老師的耐心解答和悉心教導(dǎo)。在提交和合并pr的過程中,我還第一次接觸大型ci測試,以及學(xué)習了git的各種進階用法,雖然剛開始學(xué)習的時候有些無助,但我還是最終解決了這些問題,最終完成了pr的merge。
雖然我在其中多數(shù)時候趕著ddl,但我認識到了提前量的重要性,提前聯(lián)系導(dǎo)師,或許能申請到更合心意的項目,規(guī)劃好項目計劃按時完成甚至提前完成,給自己更輕松的掌控感,也防止工作量超出預(yù)期無法完成任務(wù)。下一次,就不再當一個死線戰(zhàn)士啦。
回顧這段經(jīng)歷,我要感謝開源之夏組委會和Curve社區(qū)提供的平臺,感謝wine93老師的指導(dǎo),感謝我的同伴給予我參加的勇氣,感謝在deadline之前仍然認真勇敢沉下心來做事的自己。在這次項目中,我第一次合并pr,第一次擺脫玩具項目,第一次對于開源這件事有了初步的認識。
我想,完成了這個項目,我的開源之路才剛剛踏上征程。
# 開源之夏個人隨訪
--自我介紹--
OSPP:請簡單介紹一下自己,并說一下自己的開源經(jīng)歷吧。
陳欣怡:大家好~我是南京大學(xué)軟件工程專業(yè)的陳欣怡,在本次開源之夏中我參與的Curve社區(qū)的初級項目,是我第一次參與開源社區(qū),接觸開源,在瀏覽社區(qū)的貢獻者文檔、查看之前的issue和pr中、和社區(qū)貢獻者的交流中,我打破了對開源社區(qū)的畏懼心理,覺得參與開源是一件由淺入深、小白也可以逐步上手的事情。
OSPP:你眼中的開源是什么樣的?據(jù)了解,你所在的高校開源氛圍頗為濃厚,你認為參與開源對于計算機專業(yè)的大學(xué)生來說是必要的嗎?
陳欣怡:在我眼里的開源,也許是程序員的一種浪漫吧,開源社區(qū)構(gòu)建了一個生態(tài),人們可以查閱、修改代碼,可以提出bug和issue暴露缺陷,也可以提供pr解決問題,自主、自由、開放地開發(fā)。
我覺得開源對于計算機專業(yè)地大學(xué)生來說不是必要的,但是是很推薦去參與的。最初參與的途徑可以是ospp這樣的暑期活動,也可以各個社區(qū)組織的開發(fā)者活動,也可以是自己感興趣的good first issue。參與開源好處多多,提升個人代碼能力和解決問題的能力,提升對于工業(yè)級項目和大型項目的認知,為自己的簡歷增添履歷等等。
OSPP:參與開源項目開發(fā)實踐與在課堂上進行的實踐學(xué)習有什么不同?
陳欣怡:課堂的實踐學(xué)習通常都比較小型、基礎(chǔ)、有退路,而開源項目比較大型、復(fù)雜,遵守嚴格的開發(fā)規(guī)范和開發(fā)流程,是需要實際投入使用和與別人交互的代碼。
--參與開源之夏--
OSPP:在開源之夏的項目開發(fā)過程中,你有遇到什么困難或挑戰(zhàn)么?你是如何克服的呢?有哪些收獲?
陳欣怡:由于個人技術(shù)棧并不完全符合項目要求,一開始在理解項目和構(gòu)建項目環(huán)境上有些困難,通過不斷學(xué)習、閱讀文檔、google等方法,嘗試自己解決問題。當然,有些自己實在解決不了的還是會詢問導(dǎo)師,很感謝溫柔、悉心指導(dǎo)的wine93老師。其實說實話,由于之前做的都是課程項目或者團隊項目,遇到自己解決不了的問題,再不濟也可以問大腿朋友。但這次是獨立開發(fā),最需要最能夠依靠的還是自己,在這次經(jīng)歷中,也許才真正具備了程序員的基本素養(yǎng)之一——獨立解決問題的能力。閱讀報錯信息、抓住關(guān)鍵問題、詢問搜索引擎和生成式AI,用別人提出的各種方式嘗試解決問題的感覺真的很好。
OSPP:對于在活動中選擇社區(qū)、挑選項目、與導(dǎo)師溝通、撰寫申請書方面,有什么經(jīng)驗或建議可以分享給大家么?
陳欣怡:在尋找合適項目、提交項目申請書的方面,最建議做到的是,盡早搜尋,盡早投遞,盡早交流。在我這次申請的過程中,就犯了ddl戰(zhàn)士的老毛病,拖到了最后一刻。在琳瑯滿目的項目中四處搜尋,最后撰寫項目申請書也比較匆忙。如果有意向報名開源之夏的話,建議在項目公布之后,就迅速尋找感興趣的項目,及時聯(lián)系導(dǎo)師,然后著手做一些社區(qū)的good first issue了解社區(qū),然后充分地撰寫自己的項目申請書。總之,不要做死線戰(zhàn)士,留足提前量啦!
--寄語--
OSPP:有什么話想對計劃參加開源之夏活動的學(xué)弟學(xué)妹們說?
陳欣怡:帶著敢于嘗試、勇于交流提問、認真鉆研思考的心勇敢地往前沖吧,參與開源最難的,也許是邁出第一步的勇氣。
END
專欄編輯:大夢
校對:校大山、陳欣怡
制圖:GoodWhite

專欄投稿請聯(lián)系開源小助手:kaiyuanzhixia 或?qū)诰庉嫞篐ungryfish34(備注“專欄投稿”加速通過),或填寫下方專訪信息收集問卷。
