2011-01-02 15 views
19

Trato de construir mi aplicación con CMake en Mac OS X, me sale el siguiente error:"ld: opción desconocida: -soname" en OS X

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 

Esto es extraño, ya que Mac tiene .dylib extensión en lugar de .so.

Ahí está mi 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) 

No hubo error en Linux.

proceso de fabricación:

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

he hallado: que generan comando incorrecto en CMakeFiles/sml.dir/link.txt. Pero ¿por qué, como el objetivo de CMake es de plataformas cruzadas ...

¿Cómo corregirlo?

+0

No sé CMake, pero aquí hay una sugerencia: intente ver los proyectos basados ​​en CMake construidos bajo MacPorts o Fink ya que los parchean para compilar en Mac OS X. –

Respuesta

5

Bien, encontré dónde estaba el problema. Antes de compilar, debe eliminar todas las carpetas y archivos temporales de CMake, p. CMakeFiles, CMakeCache.txt, Makefile. Como en mi caso, el problema fue que construí ese proyecto en Linux y no eliminé estos archivos ... Es por eso que hay .so extensión ...

+0

:) Para evitar ese error, si quiero construir nuevos archivos de proyecto, siempre rm -rf compila y luego ejecuto cmake. –

+5

No debe compilar el proyecto dentro del árbol de origen, en su lugar cree un directorio de compilación fuera del árbol de origen. – RobertJMaynard

+0

Tengo un problema similar -> http://stackoverflow.com/questions/31588546/set-cmake-to-use-dyld-options-instead-gnu-ld-options-under-os-x. Lamentablemente, su solución no se aplica a mi problema.¿Puede decir qué compiladores está utilizando y cómo los está invocando con CMake? – fotinsky

53

Tuve un problema similar en OS X que resolví usando el interruptor install_name en lugar de soname.

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

¿Por qué tenemos que hacer esto? – Blaze349

+0

¿Alguien tiene una buena explicación? –

1

desactivó que eres problema, pero quería proporcionar esta es una referencia para futuros visitantes porque hay un poco más a la creación de una biblioteca dinámica en OS X. También vea Creating Dynamic Libraries en las páginas de desarrolladores de Apple.

OS X no utiliza la convención libcoolstuff.so.X.Y.Z. OS X usa la convención libcoolstuff.X.dylib. Para incrustar X.Y.Z en la biblioteca, use -install_name, -current_version y -compatibility_version.

No sé Cmake, pero así es como se ve en Make. Su receta para construir el libcoolstuff 1.0.6 será parecida:

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) 

Y la regla make install se vería así:

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 

Bajo otool, que parece:

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

último , lo usaría como se esperaba:

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