2013-10-02 18 views
5
cmake 2.8 
gcc (GCC) 4.8.1 

Sửa ----------liên kết một thư viện chia sẻ với tĩnh học sử dụng CMake

Bao bì các thư viện tĩnh trong whole-archive tác phẩm cho mỗi thư viện, ngoại trừ pjmedia-videodev Vấn đề bây giờ là khi tôi cố gắng và xây dựng tôi nhận được lỗi sau.

cbar_factory_init': colorbar_dev.c:(.text+0x2a0): undefined reference to pjmedia_format_init_video' 

Xin chào,

tôi đã tạo ra một thư viện chia sẻ và tôi cần phải liên kết thư viện mà có khoảng 10 thư viện tĩnh. Sau đó tôi liên kết tệp thực thi của tôi với thư viện được chia sẻ.

Câu hỏi của tôi là khi tôi chạy làm cho nó không liên kết vì nó cũng muốn các thư viện tĩnh. Mục đích của việc tạo ra một trình bao bọc cho các thư viện tĩnh. Vì vậy, tệp thực thi chỉ phải liên kết với 1 thư viện được chia sẻ duy nhất. Khi tôi liên kết thư viện được chia sẻ với các số liệu thống kê, thì các thống kê sẽ tự động trở thành một phần của mã nguồn của thư viện được chia sẻ.

Chỉ mã sippnets mã ngắn gọn. Trong CMakeLists.txt tôi tạo ra các thư viện chia sẻ và liên kết các thư viện tĩnh:

add_library(app_module_sip SHARED app_module_sip_init.c) 

set(PJSIP_LIBRARIES 
    g7221codec 
    gsmcodec 
    ilbccodec 
    milenage 
    pj 
    pjlib-util 
    pjmedia 
    pjmedia-codec 
    pjmedia-audiodev 
    pjmedia-videodev 
    pjnath 
    pjsip 
    pjsip-simple 
    pjsip-ua 
    pjsua 
    portaudio 
    resample 
    speex 
    srtp 
) 

target_link_libraries(app_module_sip pthread m uuid nsl rt asound crypto ssl ${PJSIP_LIBRARIES}) 

Bây giờ CMakeLists.txt của tôi mà làm cho thực thi

add_executable(app sip_test.c) 

target_link_libraries(app app_module_sip) 

là đúng này những gì tôi đang làm gì ở đây. Tôi không muốn liên kết tệp thực thi với các thư viện tĩnh. Chỉ cần một thư viện được chia sẻ vì đó là trình bao bọc của tôi, tôi sẽ gọi các hàm này.

Nó liên kết ok, nếu tôi liên kết tất cả các thư viện thống kê khi thực thi, nhưng đó không phải là kết quả tôi muốn.

Rất cám ơn cho bất cứ đề nghị,

Trả lời

1
# Location for shared library 
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libs) 

# Create shared library 
add_library(app_module_sip SHARED app_module_sip_init.c) 

# compile and link for 32 bit mode 
set_target_properties(app_module_sip PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 

# PJSIP static libraries 
set(PJSIP_LIBRARIES 
    pjsua 
    pjsip-ua 
    pjsip-simple 
    pjsip 
    pjmedia-codec 
    pjmedia-videodev 
    pjmedia 
    pjmedia-audiodev 
    pjnath 
    pjlib-util 
    resample 
    milenage 
    srtp 
    gsmcodec 
    speex 
    ilbccodec 
    g7221codec 
    portaudio 
    pj 
) 

# Wrap the static libraries in to the shared library 
target_link_libraries(app_module_sip -Wl,--start-group ${PJSIP_LIBRARIES} -Wl,--end-group 
    m uuid nsl rt pthread asound crypto ssl) 

Cần phải quấn các thư viện pjsip sẽ lệnh mối liên kết sau -Wl, - bắt đầu nhóm * .a -Wl, - cuối cùng nhóm.

Điều đó giải quyết được vấn đề của tôi.

+0

Khi tôi liên kết app_module_sip với myapp, CMake dường như thêm tất cả các thư viện của cháu như pjsua * ngoài * app_module_sip và các đối tượng trùng lặp làm lộn xộn quá trình khởi tạo tĩnh, chưa kể đến kích thước nhị phân cồng kềnh. – nodakai

3

tôi đã cố gắng để kiểm tra giải pháp của tôi, nhưng CMakeLists.txt của bạn làm việc cho tôi mà không cần bất kỳ thay đổi. Tuy nhiên, nhìn vào câu hỏi này: Include static lib in dynamic lib, nó xuất hiện mà bạn nên thử

target_link_libraries(app_module_sip ... ssl -Wl,-whole-archive ${PJSIP_LIBRARIES} -Wl,-no_whole-archive) 

(cuộn đến cuối cùng, đó là một dòng dài)

+0

Điều đó đã hiệu quả đối với tôi. Tuy nhiên, thư viện tĩnh của tôi tôi cố gắng liên kết không thành công với libpjmedia-videodev.a (colorbar_dev.o): Trong hàm 'cbar_factory_init ': colorbar_dev.c: (. Text + 0x2a0): undefined tham chiếu đến' pjmedia_format_init_video'. Tuy nhiên, nếu tôi xóa thư viện tĩnh pjmedia-videodev thì mọi thứ biên dịch, xây dựng và chạy. Không chắc tại sao thư viện đó lại thất bại. Tôi không cần phải làm bất kỳ nhân viên video nào vào lúc này, nhưng sau này tôi sẽ cần nó. Cám ơn vì sự gợi ý. – ant2009

2

Nó không phải là đơn giản.

Bạn có thể xem bằng cách sử dụng '-Wl, - toàn bộ lưu trữ' hoặc '-Wl, - xuất tất cả các biểu tượng' tùy thuộc vào nền tảng của bạn, nhưng không có cách nào tốt để làm điều này. Mọi thứ đều khác nhau, và các cửa sổ đóng một trò chơi hoàn toàn khác bằng cách sử dụng lib.exe.

Bạn có thể muốn làm điều gì đó như thế này:

http://www.mail-archive.com/[email protected]/msg01890.html

... và thêm hỗ trợ đặc biệt dành cho các nền tảng mà bạn muốn hỗ trợ, cùng một lúc.

+0

@ Doug, bài viết đó là năm 2006 và -all và -notall không còn tồn tại nữa. Phiên bản ld hiện tại của tôi là 'GNU ld phiên bản 2.23.51.0.1-10.fc18' Tôi đoán nó đã được gỡ bỏ tại một số điểm. Cảm ơn. – ant2009

+0

@ ant2009 không, ý tôi là, sử dụng IF ("$ {CMAKE_SYSTEM}" MATCHES IRIX) ... NẾU (APPLE) ... IF (WIN32) ... vv Tức là. Bạn phải chỉ định thủ công các cờ biên dịch khác nhau cho mỗi nền tảng bạn muốn hỗ trợ. Không có cách 'tổng quát' để làm điều này, đó là nền tảng chéo. – Doug

Các vấn đề liên quan