2011-01-02 27 views
19

tôi cố gắng để xây dựng ứng dụng của tôi với CMake trên Mac OS X, tôi nhận được lỗi sau:"ld: Tùy chọn unknown: -soname" trên 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 

Đây là kỳ lạ, như Mac có .dylib mở rộng thay vì .so.

Có CMakeLists.txt tôi:

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) 

Không có lỗi trên Linux.

quá trình xây dựng:

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

tôi thấy, mà lệnh không chính xác tạo ra trong CMakeFiles/sml.dir/link.txt. Nhưng tại sao, vì mục tiêu của CMake là đa nền tảng ..

Cách khắc phục?

+0

Tôi không biết CMake, nhưng đây là gợi ý: hãy thử xem các dự án dựa trên CMake được xây dựng trong MacPorts hoặc Fink vì chúng vá chúng để xây dựng trên Mac OS X. –

Trả lời

5

OK, tôi đã tìm thấy sự cố ở đâu. Trước khi tạo, bạn phải xóa tất cả các tệp và thư mục tạm thời của CMake, ví dụ: CMakeFiles, CMakeCache.txt, Makefile. Như trong trường hợp của tôi, vấn đề là tôi đã xây dựng dự án đó trên Linux và không xóa các tệp này ... Đó là lý do tại sao có phần mở rộng .so ...

+0

:) Để tránh nhầm lẫn, nếu tôi muốn xây dựng tập tin dự án mới, tôi luôn luôn rm -rf xây dựng và sau đó chạy cmake. –

+5

Bạn không nên xây dựng dự án bên trong cây nguồn, thay vào đó tạo một thư mục xây dựng bên ngoài cây nguồn. – RobertJMaynard

+0

Tôi đang gặp sự cố tương tự -> http://stackoverflow.com/questions/31588546/set-cmake-to-use-dyld-options-instead-gnu-ld-options-under-os-x. Thật không may, giải pháp của bạn không áp dụng cho vấn đề của tôi.Bạn có thể nói những trình biên dịch nào bạn đang sử dụng và cách bạn gọi chúng bằng CMake? – fotinsky

53

Tôi gặp sự cố tương tự trên OS X mà tôi đã giải quyết bằng cách sử dụng công tắc install_name thay vì soname.

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

Tại sao chúng ta phải làm điều này? – Blaze349

+0

Có ai có lời giải thích hay không? –

1

Bạn đã xóa vấn đề bạn đang, nhưng tôi muốn cung cấp này một là một tài liệu tham khảo dành cho du khách trong tương lai bởi vì có nhiều hơn một chút để tạo ra một thư viện động trên OS X. Cũng xem Creating Dynamic Libraries trong các trang Developer của Apple.

OS X không sử dụng quy ước libcoolstuff.so.X.Y.Z. OS X sử dụng quy ước libcoolstuff.X.dylib. Để nhúng X.Y.Z vào thư viện, hãy sử dụng -install_name, -current_version-compatibility_version.

Tôi không biết Cmake, nhưng dưới đây là giao diện của nó. công thức nấu ăn của bạn để xây dựng libcoolstuff 1.0.6 sẽ trông giống như:

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) 

Và quy tắc make install của bạn sẽ trông như thế:

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 

Dưới otool, nó trông giống như:

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

Cuối cùng , bạn sẽ sử dụng nó như mong đợi:

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