Por que um projeto não pode ser compilado com link de símbolo?

1

Estou trabalhando em uma equipe que desenvolve um projeto de C ++ (ROS).

Por alguma razão, não temos um bom gerenciamento de git.

Temos vários ramos git. Para compilar o projeto, tenho que git clone dos códigos de cada ramificação e reorganizar a estrutura dos diretórios.

Primeiro, eu mkdir -p /home/me/repo , depois eu git clone os códigos de cada ramificação e coloco todos eles em /home/me/repo .

Agora preciso reorganizar a estrutura, eis o que fiz:

#!/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

Eu criei esse script para compilar o projeto e funcionou. Como você pode ver, eu simplesmente copiei e reorganizei alguns diretórios e compilados.

Agora estou pensando que cp -r não é uma boa ideia porque demorou muito tempo. Eu quero usar ln -s para fazer a mesma coisa. Então eu escrevi outro script como abaixo:

#!/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

No entanto, recebi um erro:

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'

Eu verifiquei o cd /home/me/project2/src/hdmap/../third_party/ubuntu1604/opencv-3.3.1/include , ele existe.

Existem algumas razões pelas quais cp -r pode compilar, mas ln -s não pode?

    
por Yves 23.03.2018 / 07:12

1 resposta

1

Acessar .. não funciona como você espera quando os links simbólicos estão envolvidos ...

E quando você tenta isso no bash, o bash tenta ser "útil" e conserta isso para você, então o problema não se torna aparente.

Mas, resumindo, quando você vai para /home/me/project2/src/hdmap/../third_party , o kernel primeiro resolve o symlink de "hdmap", chegando a /home/me/repo/robot_dev/cognition/hdmap , e então procura .. , que significa o diretório pai de diretório hdmap, então /home/me/repo/robot_dev/cognition e então ele tentará encontrar um third_party lá.

Considerando que /home/me/repo/robot_dev/cognition/third_party não existe (ou, se ocorrer, não é o mesmo que /home/me/repo/sim/third_party , que é o que você quer), você recebe um erro de arquivo não encontrado.

O Bash mantém uma variável $PWD com o caminho armazenado como uma string, e por isso pode ajudar a "resolver" as referências .. no próprio shell antes de passar um caminho ao kernel ... Dessa forma, ele esconder esses detalhes de você.

Você pode desativar esse comportamento usando set -P (ou set -o physical ) no bash. (Veja man page bash para mais detalhes).

Para ajudá-lo com seu problema subjacente ... Talvez uma solução decente seja usar cp -rl para copiar as árvores. A opção -l para cp cria hardlinks. Isso não deve ser um problema neste caso, particularmente porque imagino que você não esteja esperando modificar os arquivos. Ele ainda terá que percorrer a estrutura de dados e criar cada objeto individualmente, mas não precisará criar nenhum conteúdo ...

Se você estiver trabalhando em um sistema de arquivos moderno (como o Btrfs), você também pode tentar o cp -r --reflink , que cria uma cópia CoW (copy-on-write). É essencialmente um hardlink, mas um pouco melhor já que não há conexão entre os dois nomes, eles estão apenas compartilhando blocos no backend, tocar em um dos arquivos irá realmente dividi-los em dois arquivos separados. (Mas eu imagino que os hardlinks provavelmente são bons o suficiente para você.)

Talvez existam alguns truques que você poderia fazer com o git, a fim de expor o diretório que você precisa em cada etapa ... Então você pode realmente clonar as partes que você precisa ... Mas isso pode ser mais difícil de realizar ou manter ... Espero que cp -rl seja suficiente para você!

    
por 23.03.2018 / 07:25