為什麼項目不能用符號連結編譯
我在一個開發 c++ (ROS) 項目的團隊中工作。
出於某種原因,我們沒有一個好的 git 管理。
我們有幾個 git 分支。要編譯項目,我必須
git clone
從每個分支中提取程式碼並重新排列目錄結構。首先,我
mkdir -p /home/me/repo
,然後我git clone
來自每個分支的程式碼並將它們全部放入/home/me/repo
.現在我需要重新排列結構,這就是我所做的:
#!/bin/sh mkdir -p /home/me/project/src cd /home/me/project/src catkin_init_workspace # command of ROS to initialize a workspace cp -r /home/me/repo/robot_dev/control . cp -r /home/me/repo/robot_dev/control_algo . cp -r /home/me/repo/sim/third_party . cp -r /home/me/repo/planning . cp -r /home/me/repo/robot_dev/cognition/hdmap . cd .. catkin_make # command of ROS to compile the project
我創建了這樣一個腳本來編譯項目並且它工作。如您所見,我只是複制並重新排列了一些目錄並進行了編譯。
現在我認為這
cp -r
不是一個好主意,因為它花費了太多時間。我想用ln -s
做同樣的事情。所以我寫了另一個腳本如下:#!/bin/sh mkdir -p /home/me/project2/src cd /home/me/project2/src catkin_init_workspace # command of ROS to initialize a workspace ln -s /home/me/repo/robot_dev/control control ln -s /home/me/repo/robot_dev/control_algo control_algo ln -s /home/me/repo/sim/third_party third_party ln -s /home/me/repo/planning planning ln -s /home/me/repo/robot_dev/cognition/hdmap hdmap cd .. catkin_make # command of ROS to compile the project
但是,我收到一個錯誤:
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:297 (message): catkin_package() absolute include dir '/home/me/project2/src/hdmap/../third_party/ubuntu1604/opencv-3.3.1/include'
我查過了
cd /home/me/project2/src/hdmap/../third_party/ubuntu1604/opencv-3.3.1/include
,確實存在。有什麼原因
cp -r
可以編譯但ln -s
不能嗎?
當涉及符號連結時,訪問
..
並沒有真正像您期望的那樣工作……當您在 bash 中嘗試時,bash 會嘗試“提供幫助”並為您修復它,因此問題不會變得明顯。
但是,簡而言之,當你去 時
/home/me/project2/src/hdmap/../third_party
,核心會先解析“hdmap”的符號連結,去/home/me/repo/robot_dev/cognition/hdmap
,然後查找表示那個hdmap 目錄..
的父目錄,然後它會嘗試在那裡找到一個third_party ./home/me/repo/robot_dev/cognition
考慮
/home/me/repo/robot_dev/cognition/third_party
不存在(或者,如果存在,它與/home/me/repo/sim/third_party
您想要的不一樣),您會得到一個文件未找到錯誤。Bash 會保留一個
$PWD
變數,並將路徑儲存為字元串,因此它可以幫助“解析”..
shell 本身中的引用,然後再將路徑傳遞給核心……這樣,它將對您隱藏這些細節。您可以在 bash 中使用
set -P
(或)禁用該行為。set -o physical
(有關更多詳細資訊,請參見 bash 手冊頁。)為了幫助您解決潛在的問題……也許一個不錯的解決方案是使用
cp -rl
複制樹。創建硬連結的-l
選項。cp
在這種情況下,這應該不是問題,特別是因為我想您不希望修改文件。它仍然需要遍歷資料結構並單獨創建每個對象,但它不必創建任何內容……如果您正在使用現代文件系統(例如 Btrfs),您還可以嘗試
cp -r --reflink
創建 CoW(寫入時複製)副本。它本質上是一個硬連結,但稍微好一點,因為這兩個名稱之間沒有聯繫,它們只是在後端共享塊,觸摸其中一個文件實際上會將它們分成兩個單獨的文件。(但我想硬連結對你來說可能已經足夠好了。)也許你可以用 git 做一些技巧,以便在每個步驟中公開你需要的目錄……所以你實際上可以複製你需要的部分……但這可能更難完成或維護…… .希望
cp -rl
對你來說足夠了!