Macaulay2 / homebrew-tap

The Macaulay2 tap for Homebrew
7 stars 6 forks source link

Don't link with libraries in the Cellar #163

Open mahrud opened 2 years ago

mahrud commented 2 years ago

boost and givaro libraries are linked using the Cellar path, which means every time that either library is updated (mainly boost) M2 requires relinking.

2022-11-13T10:22:43.9189153Z Homebrew libraries:
/home/linuxbrew/.linuxbrew/Cellar/boost/1.80.0/lib/libboost_stacktrace_backtrace-mt.so.1.80.0 (boost)
/home/linuxbrew/.linuxbrew/Cellar/givaro/4.2.0/lib/libgivaro.so.9 (macaulay2/tap/givaro)

Avoiding this reduces the need for building new revisions considerably.

mahrud commented 1 year ago

Now @tom111 is running into the same issue with libicu:

$ ldd `which M2-binary` | grep Cellar
    libgivaro.so.9 => /home/linuxbrew/.linuxbrew/Cellar/givaro/4.2.0/lib/libgivaro.so.9 (0x00007f7177544000)
    libicudata.so.72 => /home/linuxbrew/.linuxbrew/Cellar/icu4c/72.1/lib/libicudata.so.72 (0x00007f7171200000)
tom111 commented 1 year ago

I asked chatGPT about this and here was one suggestion that might be worth a try:

Solution 3: Dynamic Library Versioning A more robust and complex solution is to address the versioning problem at the root. Software should ideally be linked against a "compatibility version" of a dynamic library, not a specific version. This version indicates the minimum version of the library that the software requires and allows it to use that version or any newer one.

This is usually controlled by linker options when building the software, such as -compatibility_version and -current_version in gcc. It might require modifications to the build scripts of the software to ensure these options are used correctly. For more details, see the man pages for ld and libtool on MacOS.

There is more info here: https://chat.openai.com/share/03ac0508-78ff-4d7c-a59c-473a7ccfd8d9

I think in the case of issue #187 it seems to be the major version bump from 72 to 73 causing the issue (72 vs. 72.1 seems to be fine):

 ~ otool -L /usr/local/bin/M2-binary
/usr/local/bin/M2-binary:
    /usr/local/opt/libomp/lib/libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
    /usr/local/opt/icu4c/lib/libicudata.72.dylib (compatibility version 72.0.0, current version 72.1.0)
    /usr/local/opt/icu4c/lib/libicui18n.72.dylib (compatibility version 72.0.0, current version 72.1.0)
    /usr/local/opt/icu4c/lib/libicuuc.72.dylib (compatibility version 72.0.0, current version 72.1.0)
mahrud commented 1 year ago

Thanks, but that's not helpful at all. For one, we are never linking with any of the libicu libraries directly; a bottled boost library that we are linking with is dependent on them (either boost-regex, boost-stacktrace, or boost-math). It would be helpful if you could figure out which one is the culprit.

Alternatively, it would be helpful to find out which symbols in those libraries are used by M2-binary and maybe try to remove that from our code if possible.

tom111 commented 1 year ago

Hmm. Cutting out the code that uses this seems like a bad approach, too. I still don't understand how linking on MacOS works and who is to blame. Some more observations:

(Sorry if my suggestions are stupid, I just have vague memories how thinks worked with linux package managers...)

mahrud commented 1 year ago

Cutting out the code that uses this seems like a bad approach, too.

We don't use icu libraries in M2. They sort of tag along with some boost libraries, so it could be possible to somehow indicate to boost at compile time that we don't need these features that we don't use so that they are not linked.