2011-01-02 15 views
19

cerco di costruire la mia app con CMake su Mac OS X, ottengo il seguente errore:"ld: opzione sconosciuta: -soname" su 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 

Questo è strano, come Mac ha .dylib estensione invece di .so.

C'è la mia 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) 

Non c'era alcun errore su Linux.

processo di compilazione:

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

ho trovato, che generano comando errato in CMakeFiles/sml.dir/link.txt. Ma perché, come l'obiettivo di CMake è cross-platforming ..

Come risolvere il problema?

+0

Non conosco CMake, ma ecco un suggerimento: prova a guardare i progetti basati su CMake creati con MacPorts o Fink poiché li correggono per creare su Mac OS X. –

risposta

5

OK, ho trovato il problema. Prima della compilazione, è necessario rimuovere tutte le cartelle e i file temporanei di CMake, ad es. CMakeFiles, CMakeCache.txt, Makefile. Come nel mio caso, il problema era che ho costruito quel progetto su Linux e non ho cancellato questi file ... Ecco perché c'è l'estensione .so ...

+0

:) Per evitare tale errore, se voglio costruire nuovi file di progetto, ho sempre rm -rf build e quindi eseguire cmake. –

+5

Non si dovrebbe creare il progetto all'interno dell'albero di origine, ma creare una directory di compilazione all'esterno dell'albero di origine. – RobertJMaynard

+0

Sto riscontrando un problema simile -> http://stackoverflow.com/questions/31588546/set-cmake-to-use-dyld-options-instead-gnu-ld-options-under-os-x. Sfortunatamente, la tua soluzione non si applica al mio problema.Puoi dire quali compilatori stai utilizzando e come li stai invocando con CMake? – fotinsky

53

Ho avuto un problema simile su OS X che ho risolto usando lo switch install_name anziché soname.

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

Perché dobbiamo farlo? – Blaze349

+0

Qualcuno ha una buona spiegazione? –

1

è stata deselezionata voi sono problemi, ma ho voluto fornire questo a s un punto di riferimento per i futuri visitatori perché c'è un po 'di più per la creazione di una libreria dinamica su OS X. Vedere anche Creating Dynamic Libraries nelle pagine sviluppatori di Apple.

OS X non utilizza la convenzione libcoolstuff.so.X.Y.Z. OS X utilizza la convenzione libcoolstuff.X.dylib. Il, per incorporare X.Y.Z nella libreria, utilizzare -install_name, -current_version e -compatibility_version.

Non conosco Cmake, ma ecco come appare sotto Make. La tua ricetta per costruire il libcoolstuff 1.0.6 sarà simile:

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) 

E la regola make install sarà simile:

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 

Sotto otool, sembra che:

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

Infine , lo utilizzeresti come previsto:

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