"ld: unknown option: -soname" on OS X

34,869

Solution 1

OK, I found where problem was. Before build, you have to remove all CMake temp folders and files, e.g. CMakeFiles, CMakeCache.txt, Makefile. As in my case, issue was that I built that project on Linux and didn't delete these files... That's why there's .so extension...

Solution 2

I had a similar issue on OS X which I resolved using the the install_name switch instead of soname.

gcc -shared <files> -lc -Wl,-install_name,<libname>.so, -o <libname>.so.1

Solution 3

You cleared you're problem, but I wanted to provide this a s a reference for future visitors because there's a bit more to creating a dynamic library on OS X. Also see Creating Dynamic Libraries in the Apple Developer pages.

OS X does not use the convention libcoolstuff.so.X.Y.Z. OS X uses the convention libcoolstuff.X.dylib. The, to embed X.Y.Z into the library, use -install_name, -current_version and -compatibility_version.

I don't know Cmake, but here's how it looks under Make. Your recipe to build the libcoolstuff 1.0.6 will look like:

libcoolstuff libcoolstuff.dylib:
    $(CC) $(CFLAGS) -dynamiclib -install_name "libcoolstuff.1.dylib" \
    -current_version 1.0.6 -compatibility_version 1.0 -o libcoolstuff.1.dylib $(OBJS)

And your make install rule would look like:

PREFIX?=/usr/local
LIBDIR?=$(PREFIX)/lib
...

install:
    cp -f libcoolstuff.1.dylib $(LIBDIR)/libcoolstuff.1.dylib
    rm -f $(LIBDIR)/libcoolstuff.dylib
    ln -s $(LIBDIR)/libcoolstuff.1.dylib $(LIBDIR)/libcoolstuff.dylib
    install_name_tool -change "libcoolstuff.1.dylib" "$(LIBDIR)/libcoolstuff.1.dylib" $(LIBDIR)/libcoolstuff.1.dylib

Under otool, it looks like:

$ otool -L libcoolstuff.dylib 
libcoolstuff.dylib:
    libcoolstuff.1.dylib (compatibility version 1.0.0, current version 1.0.6)
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.7)

Finally, you would use it as expected:

export CFLAGS="-NDEBUG -g2 -O2 -Wall -arch ppc -arch ppc64"
make
...
Share:
34,869
Alex Ivasyuv
Author by

Alex Ivasyuv

Updated on August 29, 2020

Comments

  • Alex Ivasyuv
    Alex Ivasyuv over 3 years

    I try to build my app with CMake on Mac OS X, I get the following error:

    Linking CXX shared library libsml.so
    ld: unknown option: -soname
    collect2: ld returned 1 exit status
    make[2]: *** [libsml.so] Error 1
    make[1]: *** [CMakeFiles/sml.dir/all] Error 2
    make: *** [all] Error 2
    

    This is strange, as Mac has .dylib extension instead of .so.

    There's my CMakeLists.txt:

    cmake_minimum_required(VERSION 2.6)
    
    PROJECT (SilentMedia)
    
    SET(SourcePath src/libsml)
    
    IF (DEFINED OSS)
    SET(OSS_src
        ${SourcePath}/Media/Audio/SoundSystem/OSS/DSP/DSP.cpp
        ${SourcePath}/Media/Audio/SoundSystem/OSS/Mixer/Mixer.cpp
    )
    ENDIF(DEFINED OSS)
    
    IF (DEFINED ALSA)
    SET(ALSA_src
        ${SourcePath}/Media/Audio/SoundSystem/ALSA/DSP/DSP.cpp
        ${SourcePath}/Media/Audio/SoundSystem/ALSA/Mixer/Mixer.cpp
    )
    ENDIF(DEFINED ALSA)
    
    SET(SilentMedia_src
    
        ${SourcePath}/Utils/Base64/Base64.cpp
        ${SourcePath}/Utils/String/String.cpp
        ${SourcePath}/Utils/Random/Random.cpp
    
        ${SourcePath}/Media/Container/FileLoader.cpp
    
        ${SourcePath}/Media/Container/OGG/OGG.cpp
    
        ${SourcePath}/Media/PlayList/XSPF/XSPF.cpp
        ${SourcePath}/Media/PlayList/XSPF/libXSPF.cpp
        ${SourcePath}/Media/PlayList/PlayList.cpp
    
        ${OSS_src}
        ${ALSA_src}
    
        ${SourcePath}/Media/Audio/Audio.cpp
        ${SourcePath}/Media/Audio/AudioInfo.cpp
        ${SourcePath}/Media/Audio/AudioProxy.cpp
    
        ${SourcePath}/Media/Audio/SoundSystem/SoundSystem.cpp
        ${SourcePath}/Media/Audio/SoundSystem/libao/AO.cpp
    
        ${SourcePath}/Media/Audio/Codec/WAV/WAV.cpp
        ${SourcePath}/Media/Audio/Codec/Vorbis/Vorbis.cpp
        ${SourcePath}/Media/Audio/Codec/WavPack/WavPack.cpp
        ${SourcePath}/Media/Audio/Codec/FLAC/FLAC.cpp
    )
    
    SET(SilentMedia_LINKED_LIBRARY
        sml
        vorbisfile
        FLAC++
        wavpack
        ao
        #asound
        boost_thread-mt
        boost_filesystem-mt
        xspf
        gtest
    )
    
    INCLUDE_DIRECTORIES(
        /usr/include
        /usr/local/include
        /usr/include/c++/4.4
        /Users/alex/Downloads/boost_1_45_0
        ${SilentMedia_SOURCE_DIR}/src
        ${SilentMedia_SOURCE_DIR}/${SourcePath}
    )
    
    #link_directories(
    #   /usr/lib
    #   /usr/local/lib
    #   /Users/alex/Downloads/boost_1_45_0/stage/lib
    #)
    
    IF(LibraryType STREQUAL "static")
      ADD_LIBRARY(sml-static STATIC ${SilentMedia_src})
      # rename library from libsml-static.a => libsml.a
      SET_TARGET_PROPERTIES(sml-static PROPERTIES OUTPUT_NAME "sml")
      SET_TARGET_PROPERTIES(sml-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    ELSEIF(LibraryType STREQUAL "shared")
      ADD_LIBRARY(sml SHARED ${SilentMedia_src})
    
      # change compile optimization/debug flags # -Werror -pedantic
      IF(BuildType STREQUAL "Debug")
        SET_TARGET_PROPERTIES(sml PROPERTIES COMPILE_FLAGS "-pipe -Wall -W -ggdb")
      ELSEIF(BuildType STREQUAL "Release")
        SET_TARGET_PROPERTIES(sml PROPERTIES COMPILE_FLAGS "-pipe -Wall -W -O3 -fomit-frame-pointer")
      ENDIF()
    
      SET_TARGET_PROPERTIES(sml PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    ENDIF()
    
    ### TEST ###
    
    IF(Test STREQUAL "true")
      ADD_EXECUTABLE (bin/TestXSPF ${SourcePath}/Test/Media/PlayLists/XSPF/TestXSPF.cpp)
      TARGET_LINK_LIBRARIES (bin/TestXSPF ${SilentMedia_LINKED_LIBRARY})
    
      ADD_EXECUTABLE (bin/test1 ${SourcePath}/Test/test.cpp)
      TARGET_LINK_LIBRARIES (bin/test1 ${SilentMedia_LINKED_LIBRARY})
    
      ADD_EXECUTABLE (bin/TestFileLoader ${SourcePath}/Test/Media/Container/FileLoader/TestFileLoader.cpp)
      TARGET_LINK_LIBRARIES (bin/TestFileLoader ${SilentMedia_LINKED_LIBRARY})
    
      ADD_EXECUTABLE (bin/testMixer ${SourcePath}/Test/testMixer.cpp)
      TARGET_LINK_LIBRARIES (bin/testMixer ${SilentMedia_LINKED_LIBRARY})
    ENDIF (Test STREQUAL "true")
    
    ### TEST ###
    
    ADD_CUSTOM_TARGET(doc COMMAND doxygen ${SilentMedia_SOURCE_DIR}/doc/Doxyfile)
    

    There was no error on Linux.

    Build process:

    cmake -D BuildType=Debug -D LibraryType=shared .
    make
    

    I found, that incorrect command generate in CMakeFiles/sml.dir/link.txt. But why, as the goal of CMake is cross-platforming..

    How to fix it?