Не удается связать локальные библиотеки в CMake - PullRequest
1 голос
/ 13 июля 2020

Я разрабатываю программу на C ++ в Visual Studio, которая будет развернута на linux и отлажена на linux через s sh. В настоящее время это структура моей папки:

ANT
-xscommon
--xscommon_config.h
-xscontroller
-xstypes
ANT.cpp
ANT.h
CMakeLists.txt
CMakeSettings.json
hashes.h
quaternionic.h
stars.h

В настоящее время все файлы .h, .cpp, .o, .cpp.o, .a, на которые, как мне кажется, нужно ссылаться, хранятся в трех каталогах xs -------. Я новичок в cmake, и эта связь с этими библиотеками вызывает у меня проблемы; Я могу правильно ссылаться на включения, но возникают ошибки неопределенных ссылок, когда я не выполняю связывание, и когда я пытаюсь установить ссылку, возникают ошибки. Это мой текущий файл CMakeLists.txt:

# CMakeList.txt : CMake project for ANT, include source and define
# project specific logic h"ere.
#
cmake_minimum_required (VERSION 3.8)

project ("ANT")

link_directories(${ANT_SOURCE_DIR}/xscommon xscontroller xstypes)

add_executable(
    ANT
    "ANT.cpp" 
    "ANT.h" 
    "quaternionic.h" 
    "stars.h"
    "hashes.h"
)

target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(ANT PUBLIC xscommon_config)

Когда я запускаю его, построитель говорит следующее:

/usr/bin/ld: cannot find -lxscommon_config

Мне нужно найти эти библиотеки в каталоге, который ANT . cpp находится внутри, поскольку именно здесь они хранятся, однако ничто из того, что я делаю (и я уже несколько часов возился с конфигурациями), не скажет camke искать эти библиотеки в папке sr c. он всегда идет к /usr/bin/ld.

Мне действительно просто нужно знать, что сказать CMake, чтобы он выглядел в правильном месте для каждого файла, то есть если я говорю ему искать правильный файл (Я почти уверен, что да).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%

Обновление

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%

Итак, я переделал файл CMakeLists.txt на этот:

# CMakeList.txt : CMake project for ANT, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.15)

project ("ANT")

#[STATIC | SHARED | MODULE]
#[STATIC | SHARED | MODULE]
#[STATIC | SHARED | MODULE]


add_library(xscommon SHARED IMPORTED)
add_library(xscontroller SHARED IMPORTED)
add_library(xstypes SHARED IMPORTED)

add_executable(
    ANT
    "ANT.cpp" 
    "ANT.h" 
)

target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

И все еще получаю неопределенные ссылки. Вместо этого я попытаюсь собрать библиотеки. Кроме того, я связался с производителем IMU, которые используют этот SDK, так как мои коллеги тоже не смогли это исправить.

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Проблема в том, что вы связываетесь с библиотекой, которая не была создана. Этот

# link to this directory
target_link_libraries(ANT PRIVATE xscommon)

пытается связать библиотеку с именем xscommon с целевым ANT, но вы не создали xscommon нигде в своем проекте.

Если xscommon является библиотекой предварительной сборки, и вы просто хотите импортировать его, затем добавьте библиотеку и установите целевое свойство IMPORTED:

add_library(xscommon [STATIC | SHARED | MODULE] IMPORTED)

Если вы хотите создать xscommon в своем root CMakeLists.txt. Добавьте xscommon как библиотеку и укажите расположение заголовков.

add_library(xscommon [STATIC | SHARED | MODULE]
    xxx/xxx.cpp #list all source files that build the library - use relative path
)
target_include_directories(xscommon PRIVATE
   xxx/xxx #path to the location of library header files
)

Также вам не нужно добавлять файлы заголовков при добавлении исполняемого файла. Таким образом, это

add_executable(
    ANT
    "ANT.cpp" 
    "ANT.h" 
    "quaternionic.h" 
    "stars.h"
    "hashes.h"
)

можно упростить до

add_executable(
    ANT
    "ANT.cpp" 
)
0 голосов
/ 13 июля 2020

Предположим, ваш каталог выглядит следующим образом:

ANT
-xscommon
--xscommon_config.h
--xscommon_config.cpp
...

Сначала добавьте файл CMakeLists.txt в xscommon/:

ANT
-xscommon
--CMakeLists.txt
--xscommon_config.h
--xscommon_config.cpp
...

Теперь в xscommon/CMakeLists.txt мы создадим библиотеку , который будет импортирован и связан в основном файле CMakeLists.txt:

xscommon / CMakeLists.txt :

#define another target, let's name it 'xscommon'
add_library(xscommon
   xscommon_config.h
   xscommon_config.cpp
   #more sources if you want
   )

Теперь в основном файле CMakeLists.txt :

cmake_minimum_required (VERSION 3.8)

project ("ANT")

#remove this line
#link_directories(${ANT_SOURCE_DIR}/xscommon xscontroller xstypes)

add_executable(
    ANT
    "ANT.cpp" 
    "ANT.h" 
    "quaternionic.h" 
    "stars.h"
    "hashes.h"
)

# add the xscommon directory, this will make the library target defined there available here
add_subdirectory(xscommon)

# link to this directory
target_link_libraries(ANT PRIVATE xscommon)
# use PUBLIC if the xscommon library will be part of the public interface of your
# library. But since it is an executable, PRIVATE is better here.

target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

Используйте описанный выше метод, вы можете создать больше библиотек и связать их.

Обратите внимание, что не требуется создавать отдельные файлы cmake для каждого подкаталог, но это считается хорошей практикой и модулирует ваш код. Если вы хотите сделать это в основном файле cmake вместо создания подкаталога, добавьте это в основной cmake:

add_library(xscommon
   xscommon/xscommon_config.h
   xscommon/xscommon_config.cpp
   #more sources if you want
   )

Обновить в соответствии с рассматриваемыми изменениями

Ваш текущий CMakeLists.txt:

Эти три строки ниже ничего не делают, определенно не то, что вы думаете. Я знаю, что в команде add_library() есть слово «добавить», но она не добавляет никаких библиотек, как и add_executable не добавляет никаких исполняемых файлов. Он создает библиотеку.

add_library(xscommon SHARED IMPORTED)
add_library(xscontroller SHARED IMPORTED)
add_library(xstypes SHARED IMPORTED)

Как создать библиотеку в cmake из двух файлов a.cpp и a.h:

add_library(myALib "a.cpp")

Вот и все . Если у вас есть больше источников, вы, конечно, включите их соответственно. В вашем случае вам нужно будет добавить источники xscommon и другие соответственно.

После того, как вы создали библиотеки, вам нужно связать их с вашим исполняемым файлом. Если вы этого не сделаете, вы получите ошибки undefined reference , потому что компилятор может найти объявления в файлах заголовков, но не определения вашего кода, который существует в файлах .cpp.

Итак, как ты ссылку? Простой:

target_link_libraries(TARGET_NAME PUBLIC | PRIVATE LIBRARY_NAME)
# TARGET_NAME: can be `executable` or `library`
# PUBLIC or PRIVATE (for exe, it is usually private)
# LIBRARY_NAME: Name of library you want to link to TARGET_NAME

# So if you wanted to link "myALib" which I created above to ANT, you would do:
target_link_libraries(ANT PRIVATE myALib)

# Note: You need to add this line **after** add_executable() because target "ANT" will be created after that. You can do the linking after the "target_include_directories" command.
...