【问题标题】:"ld: unknown option: -soname" on OS XOS X 上的“ld:未知选项:-soname”
【发布时间】:2011-06-02 14:53:52
【问题描述】:

我尝试在 Mac OS X 上使用 CMake 构建我的应用程序,我收到以下错误:

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

这很奇怪,因为 Mac 的扩展名为 .dylib 而不是 .so。

这是我的 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)

在 Linux 上没有错误。

构建过程:

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

我发现,在CMakeFiles/sml.dir/link.txt 中生成了不正确的命令。但是为什么,因为 CMake 的目标是跨平台..

如何解决?

【问题讨论】:

  • 我不知道 CMake,但这里有一个建议:尝试查看在 MacPorts 或 Fink 下构建的基于 CMake 的项目,因为它们会修补它们以在 Mac OS X 上构建。
  • 我不知道如何或何时,但我之前不小心对这个问题投了反对票。这绝对不是我的本意。回复和赞成。道歉!

标签: macos makefile shared-libraries cmake


【解决方案1】:

我在 OS X 上遇到了类似的问题,我使用 install_name 开关而不是 soname 解决了这个问题。

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

【讨论】:

  • 我们为什么要这样做?
  • 伙计们,不同的操作系统。为什么 Windows 有 .dll 而不是 .so?你永远不知道:)
【解决方案2】:

您解决了问题,但我想为未来的访问者提供此参考,因为在 OS X 上创建动态库还有更多内容。另请参阅 Apple 开发者页面中的 Creating Dynamic Libraries

OS X 不使用约定libcoolstuff.so.X.Y.Z。 OS X 使用约定libcoolstuff.X.dylib。要将X.Y.Z 嵌入到库中,请使用-install_name-current_version-compatibility_version

我不知道 Cmake,但这是 Make 下的样子。您构建libcoolstuff 1.0.6 的方法如下:

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)

您的make install 规则如下所示:

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

otool 下,它看起来像:

$ 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)

最后,你会按预期使用它:

export CFLAGS="-NDEBUG -g2 -O2 -Wall -arch ppc -arch ppc64"
make
...

【讨论】:

    【解决方案3】:

    好的,我找到了问题所在。在构建之前,您必须删除所有 CMake 临时文件夹和文件,例如CMakeFilesCMakeCache.txtMakefile。就我而言,问题是我在Linux 上构建了该项目并且没有删除这些文件...... 这就是为什么有 .so 扩展名...

    【讨论】:

    • :) 为了避免这样的错误,如果我想构建新的项目文件,我总是 rm -rf build 然后运行 ​​cmake。
    • 你不应该在源代码树内构建项目,而是在源代码树之外创建一个构建目录。
    • 我遇到了类似的问题 -> stackoverflow.com/questions/31588546/…。不幸的是,您的解决方案不适用于我的问题。您能说出您正在使用哪些编译器以及您是如何使用 CMake 调用它们的吗?
    • 显然这不应该是正确的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-07-19
    • 2013-12-14
    • 2012-05-29
    • 2013-10-29
    • 2020-12-25
    • 2021-10-23
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多