2012-06-27 25 views
7

Tôi xin lỗi vì đã làm phiền tất cả các bạn, nhưng tôi có một chút vấn đề về biên dịch với cmake.Thư viện xây dựng với cmake

Tôi có tệp CMakeLists.txt tôi đang sử dụng để tạo tệp thi hành thử nghiệm và thư viện được chia sẻ. Cả hai đều có sự phụ thuộc vào một thư viện khác (SFML).

Tôi đang sử dụng cmake trên cửa sổ với MinGW.

Tôi biết tên của thư viện mà tôi đang xây dựng rất khó hiểu với sfml, nhưng nó được cho là một trình bao bọc SFML, vì vậy, tôi không tìm được tên nào tốt hơn!

Ở đây CMakeLists.txt

cmake_minimum_required(VERSION 2.6) 
project(projectName) 

set(EXECUTABLE_NAME testSFML) 
set(LIBRARY_NAME SFMLwindow) 

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/) 

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/
${CMAKE_CURRENT_SOURCE_DIR}/../../include 
) 

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/) 

file(
    GLOB_RECURSE 
    SRC_FILES 
    src/* 
) 

file(
    GLOB_RECURSE 
    INCLUDE_FILES 
    include/* 
) 

add_executable(
${EXECUTABLE_NAME} 
main.cpp 
${SRC_FILES} 
${INCLUDE_FILES} 
) 

target_link_libraries(
    ${EXECUTABLE_NAME} 
    sfml-main 
    sfml-system 
    sfml-window 
) 


add_library(
${LIBRARY_NAME} 
SHARED 
${SRC_FILES} 
) 

Và những gì tôi nhận được trong terminal:

"C:\MinGW\bin\mingw32-make.exe" 
-- Configuring done 
-- Generating done 
-- Build files have been written to: C:/Users/iksemel/docs/WorkBench/programming/projets/TestSFML/cmake 
Linking CXX shared library libSFMLwindow.dll 
Creating library file: libSFMLwindow.dll.a 
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x59):undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj' 
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0xda): undefined reference to `_imp___ZN2sf6WindowC1ENS_9VideoModeERKSsjRKNS_15ContextSettingsE' 
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x163): undefined reference to `_imp___ZN2sf6Window5closeEv' 
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1bd): undefined reference to `_imp___ZN2sf6Window9pollEventERNS_5EventE' 
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1d8): undefined reference to `_imp___ZN2sf6Window7displayEv' 
collect2: ld a retourné 1 code d'état d'exécution 
mingw32-make.exe[2]: *** [libSFMLwindow.dll] Error 1 
mingw32-make.exe[1]: *** [CMakeFiles/SFMLwindow.dir/all] Error 2 
mingw32-make.exe: *** [all] Error 2 

Nếu ai có một đầu mối về những gì đang xảy ra, tôi sẽ rất gratefull!

Trả lời

14

Khi đoán, thư viện SFMLwindow của bạn cần được liên kết với một số hoặc tất cả sfml-main, sfml-system, sfml-window.

Bạn có thể thử thay đổi cuối CMakeLists.txt của bạn để:

add_library(
    ${LIBRARY_NAME} 
    SHARED 
    ${SRC_FILES} 
    ${INCLUDE_FILES} 
) 

add_executable(
    ${EXECUTABLE_NAME} 
    main.cpp 
) 

target_link_libraries(
    ${LIBRARY_NAME} 
    sfml-main 
    sfml-system 
    sfml-window 
) 

target_link_libraries(
    ${EXECUTABLE_NAME} 
    ${LIBRARY_NAME} 
) 


Là một sang một bên, file(GLOB_RECURSE... thường tán thành như là một cách để thu thập một danh sách nguồn khác nhau. Từ tài liệu cho file:

Chúng tôi khuyên bạn không nên sử dụng GLOB để thu thập danh sách các tệp nguồn từ cây nguồn của bạn. Nếu không có tệp CMakeLists.txt thay đổi khi nguồn được thêm vào hoặc bị xóa thì hệ thống xây dựng được tạo không thể biết khi nào nên yêu cầu CMake tạo lại.


Ngoài ra, find_library nên được ưa thích để link_directories trong trường hợp này. Từ tài liệu cho link_directories:

Lưu ý rằng lệnh này hiếm khi cần thiết. Các vị trí thư viện được trả về bởi find_package() và find_library() là các đường dẫn tuyệt đối. Vượt qua các đường dẫn tệp thư viện tuyệt đối này trực tiếp đến lệnh target_link_libraries(). CMake sẽ đảm bảo mối liên kết tìm thấy chúng.

+0

Cảm ơn sự trợ giúp, tôi đã chỉnh sửa CMakeLists.txt của mình, nhưng có vẻ như chưa hoạt động. Nhưng điều kỳ lạ là, nếu tôi chỉ xây dựng tệp thực thi, nó hoạt động tốt, chỉ khi xây dựng thư viện mà tôi gặp phải vấn đề này. Và các tệp .o dường như được tạo ra như chúng cần. My CmakeLists.txt bây giờ: http://pastebin.com/hLux8Lvi – Cuthalion

+0

Tôi đã tìm ra vấn đề! Bạn đã đúng về vấn đề liên kết, nhưng để sửa nó, tôi đã phải sử dụng 2 target_link_libraries. Một cho thực thi và một cho thư viện. Vấn đề khác mà tôi có là lệnh điều khiển. Dường như * target_link_libraries * phải xuất hiện sau khi add_executable và add_library. Đây là cmake hiện tại của tôi, và một lần nữa, cảm ơn thông tin chung về cmake và giúp tôi! http://pastebin.com/ErgbGir0 – Cuthalion

+0

OK - vui vì nó hoạt động. Sự khác biệt chính giữa các giải pháp của chúng tôi là bạn biên dịch các nguồn vào cả thư viện * và * exe. Điều này là tốt cho các dự án nhỏ, nhưng trở thành một nỗi đau nếu bạn có rất nhiều tập tin nguồn. Thông thường, bạn sẽ biên dịch các nguồn một lần chỉ vào thư viện, sau đó chỉ cần liên kết thư viện đó với exe thử nghiệm.Với CMake, nếu bạn chỉ định rằng lib A phụ thuộc vào lib B, và exe Z phụ thuộc vào lib A, sau đó nó tự động thêm lib B như một phụ thuộc của Z nữa. Đó là lý do tại sao tôi chỉ định '$ {LIBRARY_NAME}' làm phụ thuộc của '$ {EXECUTABLE_NAME}'. Không có biggie mặc dù :-) – Fraser