2012-08-22 42 views
34

Tôi hiện đang cố gắng để có được CMake chạy cho dự án của tôi (trên cửa sổ). Tôi muốn sử dụng một vị trí tùy chỉnh nơi tất cả các thư viện được cài đặt. Để thông báo cho CMake về con đường mà tôi đã cố gắng để làm điều đó:cmake - find_library - vị trí thư viện tùy chỉnh

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs) 

Nhưng khi tôi cố gắng tìm thư viện với

find_library(CURL_LIBRARY NAMES curl curllib libcurl_imp curllib_static) 

CMake không thể tìm thấy nó. Khi tôi đặt đường dẫn tiền tố của mình thành

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs/curl) 

... thư viện được đặt.

Vì vậy, câu hỏi của tôi là: Làm thế nào tôi có thể cấu hình CMake đúng cách để làm việc với một structore thư mục tại một địa điểm tùy chỉnh mà trông như thế:

D:/develop/cmake/libs/ 
-> libA 
    -> include 
    -> lib 
-> libB 
    -> include 
    -> lib 
-> ... 
    -> include 
    -> lib 

Trong "bao gồm" nói dối các tiêu đề công cộng và trong "lib "là các thư viện được biên dịch.

Hope ai đó có thể giúp tôi - Cảm ơn trước

chỉnh sửa: Cách giải quyết hiện nay đối với tôi là, để làm điều này trước khi tôi tìm kiếm cho các thư viện:

set(CUSTOM_LIBRARY_PATH D:/develop/cmake/libs) 
file(GLOB sub-dir ${CUSTOM_LIBRARY_PATH}/*) 
foreach(dir ${sub-dir}) 
    if(IS_DIRECTORY ${dir}) 
     set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir}) 
    endif() 
endforeach() 

Nhưng cách mà các module mặc định cho tăng wont tìm thấy nó cho đến khi nó bởi vì structore thư mục của tăng là một chút khác nhau.

boost -> include -> boost-1_50 -> *.hpp 

Khi tôi di chuyển nội dung nếu "tăng-1_50" để "bao gồm" thư viện có thể được tìm thấy nhưng cách mà nó không thể xử lý nhiều phiên bản phải không?

+1

Thứ nhất, tại sao bạn thiết lập CMAKE_PREFIX_PATH bên CMakeLists.txt? Điều này sẽ không hoạt động nếu một người khác sẽ cố gắng biên dịch dự án của bạn. – arrowd

+0

Chỉ để thử nghiệm - nếu nó hoạt động, tôi sẽ sử dụng biến môi trường – Daniel

Trả lời

9

tôi thấy rằng hai người đặt câu hỏi đó vào mục yêu thích của họ vì vậy tôi sẽ cố gắng trả lời các giải pháp mà làm việc cho tôi: Thay vì sử dụng tìm module Tôi đang viết file cấu hình cho tất cả các thư viện đã được cài đặt. Những tệp đó cực kỳ đơn giản và cũng có thể được sử dụng để đặt các biến không chuẩn. CMake sẽ (ít nhất là trên cửa sổ) tìm kiếm các tệp cấu hình đó trong

CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake 

(có thể được đặt qua biến môi trường). Ví dụ: Ví dụ: cấu hình tăng cường nằm trong đường dẫn

CMAKE_PREFIX_PATH/boost-1_50/boost-config.cmake 

Trong cấu hình đó, bạn có thể đặt biến. Tệp cấu hình của tôi để tăng trông giống như sau:

set(boost_INCLUDE_DIRS ${boost_DIR}/include) 
set(boost_LIBRARY_DIR ${boost_DIR}/lib) 
foreach(component ${boost_FIND_COMPONENTS}) 
    set(boost_LIBRARIES ${boost_LIBRARIES} debug ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-gd-1_50.lib) 
    set(boost_LIBRARIES ${boost_LIBRARIES} optimized ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-1_50.lib) 
endforeach() 
add_definitions(-D_WIN32_WINNT=0x0501) 

Khá thẳng về phía trước + có thể thu nhỏ kích thước của tệp cấu hình nhiều hơn khi bạn viết một số chức năng trợ giúp. Vấn đề duy nhất tôi có với thiết lập này là tôi không tìm thấy một cách để cung cấp cho các tập tin cấu hình một ưu tiên hơn tìm mô-đun - vì vậy bạn cần phải loại bỏ các mô-đun tìm.

Hy vọng điều này hữu ích cho người khác.

15

Giải pháp đơn giản nhất có thể là thêm HINTS vào mỗi yêu cầu find_*.

Ví dụ:

find_library(CURL_LIBRARY 
    NAMES curl curllib libcurl_imp curllib_static 
    HINTS "${CMAKE_PREFIX_PATH}/curl/lib" 
) 

Đối với Boost Tôi mạnh mẽ sẽ khuyên bạn sử dụng các module chuẩn FindBoost và thiết lập các biến BOOST_DIR để trỏ đến thư viện Boost của bạn.

+0

Tôi thực hiện kết hợp các gợi ý + biến môi trường như BOOST_DIR để giúp tìm kiếm các thư viện của tôi trên các cửa sổ. Ngoài ra đối với một số thư viện nếu một mô-đun chuẩn không nhìn vào biến môi trường, tôi sẽ kiểm tra trong CMakeLists.txt của tôi nếu biến môi trường được đặt nhưng biến CMake trống và sau đó đặt biến CMake mà nó dự kiến ​​sẽ giúp nó. – drescherjm

+0

Từ khóa HINTS thực hiện tác vụ. Trong trường hợp của tôi, tôi đang sử dụng thư viện math libm.so từ một thư mục cục bộ. Nhưng mỗi khi tôi biên soạn, nó lấy nó từ thư mục hệ thống. Bằng cách sử dụng từ khóa HINTS và nêu rõ đường dẫn của libm.so, tôi có thể liên kết thành công với libm.so. – infoclogged

+0

Và khi tôi sử dụng cấu trúc này, trong dự án msvc đã tạo, tôi gặp lỗi "CURL_LIBRARY.lib not found". Tôi bị thương tại sao nó cố gắng tìm kiếm thư viện bằng tên biến, nhưng nó làm. – Arkady

6

Không có cách nào để tự động đặt CMAKE_PREFIX_PATH theo cách bạn muốn. Tôi thấy các cách sau đây để giải quyết vấn đề này:

  1. Đặt tất cả các tệp thư viện trong cùng một thư mục. Tức là, include/ sẽ chứa tiêu đề cho tất cả libs, lib/ - nhị phân, v.v. FYI, đây là bố cục chung cho hầu hết các hệ thống giống UNIX.

  2. Đặt biến môi trường toàn cục CMAKE_PREFIX_PATH thành D:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;.... Khi bạn chạy CMake, nó sẽ tự động nhận được env var này và điền nó là CMAKE_PREFIX_PATH.

  3. Viết tập lệnh bao bọc .bat, sẽ gọi cmake lệnh với đối số -D CMAKE_PREFIX_PATH=....

0

Tôi đã gặp phải một trường hợp tương tự. Tôi giải quyết nó bằng cách thêm vào đoạn mã sau này ngay trước find_library():

set(CMAKE_PREFIX_PATH /the/custom/path/to/your/lib/) 

sau đó nó có thể tìm thấy vị trí của thư viện.

+2

'CMAKE_PREFIX_PATH' có nghĩa là được đặt bởi người dùng (hoặc bất kỳ ai gọi' cmake'). Hardcoding nó có thể làm việc cho bạn, nhưng không phải trên các hệ thống khác. – usr1234567

3

Bạn có thêm một cấp làm tổ. CMAKE sẽ tìm kiếm theo $CMAKE_PREFIX_PATH/include cho tiêu đề và $CMAKE_PREFIX_PATH/libs cho thư viện.

Từ cmake documentation:

Đối với mỗi đường dẫn trong danh sách CMAKE_PREFIX_PATH, CMake sẽ kiểm tra "PATH/include" và "PATH" khi FIND_PATH() được gọi, "PATH/bin" và " PATH "khi FIND_PROGRAM() được gọi, và" PATH/lib và "PATH" khi FIND_LIBRARY() được gọi.

3

Sử dụng CMAKE_PREFIX_PATH bằng cách thêm nhiều đường (cách nhau bằng dấu chấm phẩy và không có khoảng trống trắng). Bạn có thể et nó như là một biến môi trường để tránh có đường dẫn tuyệt đối trong các tệp cấu hình cmake của bạn

Lưu ý rằng cmake sẽ tìm tệp cấu hình ở bất kỳ following folders ở đâu bạn đang tìm kiếm

<prefix>/            (W) 
<prefix>/(cmake|CMake)/         (W) 
<prefix>/<name>*/          (W) 
<prefix>/<name>*/(cmake|CMake)/       (W) 
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/   (U) 
<prefix>/(lib/<arch>|lib|share)/<name>*/    (U) 
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U) 

Trong trường hợp của bạn, bạn cần phải thêm vào CMAKE_PREFIX_PATH hai đường dẫn sau:

D:/develop/cmake/libs/libA;D:/develop/cmake/libB 
Các vấn đề liên quan