2014-10-06 2 views
3

Я хочу использовать CMake для создания простой статической библиотеки Maths, а затем ссылку на эту библиотеку для создания простого исполняемого файла Alpha.CMake не может найти файл моей библиотеки

Вот моя структура каталогов:

/Maths 
    /build 
     /
    /CMakeLists.txt 
    /maths.cpp 
    /maths.h 
/Alpha 
    /build 
     /
    /CMakeLists.txt 
    /main.cpp 

А вот содержимое этих файлов:

* CMakeLists.txt (для Математики) *

cmake_minimum_required(VERSION 2.6) 
project(Maths) 
add_library(maths STATIC maths.cpp) 

* математика .cpp *

int Double(int x) 
{ 
    int y = x * 2; 
    return y; 
} 

* * maths.h

int Double(int x); 

* CMakeLists.txt (для альфа) * ​​

cmake_minimum_required(VERSION 2.8) 
project(Alpha) 
add_executable(alpha main.cpp ../Maths/maths.h) 
target_link_libraries(maths ../Maths/build/libmaths.a) 

* main.cpp *

#include <iostream> 

#include "maths.h" 

using namespace std; 

int main() 
{ 
    int x = 5; 
    int y = Triple(x); 
    cout << "The answer = " << y << endl; 
    return 0; 
} 

Итак, я вхожу в каталог /Maths/build и запускаю cmake ... Затем я запускаю make. Это создает файл библиотеки libmaths.a в каталоге /Maths/build.

Затем я вхожу в каталог /Alpha/build и запускаю cmake ... Затем я запускаю make. Однако это дает мне сообщение об ошибке:

/usr/bin/ld: cannot find -lmaths 

Почему не удается найти файл библиотеки, который я только что создал?

Я также попытался copyiing libmaths.a и maths.h в каталог /Alpha и изменение CMakeLists.txt Альфы к:

cmake_minimum_required(VERSION 2.8) 
project(Alpha) 
add_executable(alpha main.cpp maths.h) 
target_link_libraries(maths libmaths.a) 

Но это дало ту же ошибку.

ответ

3

Важная проблема: libmaths.a не размещается ни в одной из каталогов ссылок по умолчанию. Большая проблема в том, что вы прошли libmaths.a до target_link_libraries.

Это плохо по нескольким причинам, но наиболее очевидным является то, что он полностью не переносится. Другая инструментальная цепочка компилятора может использовать другой конец, чем .a для статических библиотек, поэтому вы не сможете его построить. Кроме того, если вы когда-нибудь решите переключиться на динамическое связывание в будущем, это означает реорганизацию существующих сценариев CMake.

Правильное решение - не передавать жестко заданные имена файлов в target_link_libraries. Есть две дороги, которые вы можете предпринять, чтобы избежать этого.

  1. Используйте сценарий поиска. По существу, вы вызываете find_library(MY_MATHLIB maths [...]), а затем делаете target_link_libraries(alpha ${MY_MATHLIB}). Это определит абсолютный путь файла .a портативным способом и передаст его компоновщику. Самым большим недостатком такого подхода является то, что файл .a должен быть уже доступен для успешного поиска. Поэтому, если вы хотите построить mathsпосле, запуская CMake для alpha или создав его как часть alpha, это не сработает.

  2. Поскольку обе библиотеки находятся под вашим контролем, рассмотрите возможность использования CMake's packaging mechanism. Это, безусловно, самый удобный подход для строительства, но, к сожалению, также сложнее всего настроить. Если вы готовы потратить некоторое время на изучение документов CMake и эксперименты с сборкой, я рекомендую вам попробовать, но если вы просто хотите что-то, что работает быстро, вы можете придерживаться опции 1.

+0

Я также с той же проблемой здесь, а также просто начать работу с CMake. Я ничего не знаю о методах программирования на С ++, просто приступая к работе. Не могли бы вы объяснить свою первую рекомендацию? Потому что я не мог понять вещь в предоставленной ссылке. Если вы можете привести пример, я буду очень благодарен. – Bora

+0

@Bora Команда 'find_library' просто ищет файл библиотеки на диске. Поскольку CMake знает соглашение об именах разных компиляторов, вы просто указываете необработанное имя ('maths' в примере) без каких-либо расширений файлов, и CMake автоматически ищет правильный файл. В зависимости от вашей системы и местоположения файла вам может потребоваться дополнительные подсказки, где находится файл. Взгляните на связанную справочную страницу, чтобы получить полное объяснение правил поиска. Но, в конце концов, это действительно не что иное, как поиск файла с совпадающим именем на диске. – ComicSansMS

2

Используйте CMakeLists.txt в корневом каталоге

/CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
PROJECT(MyProject) 
ADD_SUBDIRECTORY(Maths) 
ADD_SUBDIRECTORY(Alpha) 

в Alpha/CMakeLists.txt:

TARGET_LINK_LIBRARIES(alpha maths) 

Run CMake на высшем уровне CMakeLists.txt вместо отдельных подкаталогов те

Смежные вопросы