Compiling

為什麼項目不能用符號連結編譯

  • September 7, 2018

我在一個開發 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對你來說足夠了!

引用自:https://unix.stackexchange.com/questions/432994