我在一个开发 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
不能编译呢?
答案1
..
当涉及符号链接时,访问并没有真正按照您的预期工作......
当您在 bash 中尝试这样做时,bash 会尝试“提供帮助”并为您修复它,因此问题不会变得明显。
但是,简而言之,当您转到 时/home/me/project2/src/hdmap/../third_party
,内核将首先解析“hdmap”的符号链接,到达/home/me/repo/robot_dev/cognition/hdmap
,然后查找..
这意味着 的父目录那hdmap 目录,因此/home/me/repo/robot_dev/cognition
它会尝试在那里找到third_party。
考虑到/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
对你来说足够了!