Я компилирую некоторый код, и по разным причинам я делаю это статически. На моем компьютере с Ubuntu 12.04 / gcc 4.6.3 он компилируется, работает нормально и полностью статичен:
> ldd mycode
not a dynamic executable
Все идет нормально.
Но мне также нужно запустить его на другой машине, системе Scientific Linux 5, работающей под управлением gcc 4.5.3. По какой-то причине здесь у ldd остались некоторые динамические библиотеки:
> ldd mycode
linux-vdso.so.1 => (0x00007fffd75fd000)
libstdc++.so.6 => /usr/local/swift/gcc-4.5.3/lib64/libstdc++.so.6 (0x00002b4bafab2000)
libm.so.6 => /lib64/libm.so.6 (0x000000398ca00000)
libc.so.6 => /lib64/libc.so.6 (0x000000398c600000)
/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x000000398c200000)
libgcc_s.so.1 => /usr/local/swift/gcc-4.5.3/lib64/libgcc_s.so.1 (0x00002b4bafdb8000)
Что само по себе хорошо. Код компилируется и связывается нормально, и, как видно из ldd, все зависимости разрешены. Тем не менее, когда я пытаюсь выполнить его на SL-машине, происходит сбой:
> ./mycode
/lib/ld64.so.1: bad ELF interpreter: No such file or directory
Поэтому, насколько я вижу, во время выполнения по какой-то причине /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2
ссылка не разрешается, хотя это делает ldd. Конечно, на машинах, где у меня есть root-доступ, я могу решить эту проблему, создав sym-ссылку с ld-linux-x84..blah на /lib/ld64.so.1, но это довольно сложное решение, и я не могу применить это к нашему кластеру. Если я скомпилирую все динамически, это будет работать нормально, но это означает установку всех сторонних библиотек, с которыми я собираюсь, на кучу машин, которых я хотел избежать. Наконец, все зависимости, с которыми я компилируюсь, также используются другим проектом, также скомпилированным с помощью cmake, и в этом случае у меня нет проблем, и ldd фактически перечисляет прямой каталог /lib64/ld-linux…blah, а не вызов в /lib/ld64.so.
Итак — почему это происходит? Почему я могу скомпилировать и связать код ОК, добавить его в ОК, но не выполнить его? Любые идеи будут с благодарностью приняты!
Хорошо, я думаю, что я взломал это в конце. Это были в основном аргументы компоновщика, передаваемые cmake, которые представляли собой неприятную комбинацию статических и динамических, однако добавление следующих строк в мой CMakeLists.txt исправило это:
SET_TARGET_PROPERTIES (mytarget PROPERTIES LINK_SEARCH_START_STATIC 1)
SET_TARGET_PROPERTIES (mytarget PROPERTIES LINK_SEARCH_END_STATIC 1)