Как использовать libnet с cmake (и kdevelop)?

Боюсь, что мой вопрос может быть глупым, но, поскольку я новичок в kdevelop и cmake, мне довольно сложно понять, как они работают. Проект, который я пытался настроить, использует библиотеку libnet 1.1. Мой вопрос: как мне заставить cmake скомпилировать и связать эту библиотеку, чтобы я мог правильно ее использовать?

Вот что я уже пробовал:

PROJECT(test)

include_directories("${PROJECT_SOURCE_DIR}/libnet")
add_subdirectory(libnet)

ADD_EXECUTABLE(test main.c)
target_link_libraries(test libnet)

Спасибо за помощь!

1 ответ

Решение

Похоже, что libnet не использует сам CMake, поэтому вам придется собирать его отдельно или сделать его частью вашего собственного проекта.

Чтобы построить его отдельно, у вас есть несколько вариантов. Вы можете собрать его (и установить, если хотите), а затем использовать find_library найти фактический файл libnet.a / libnet.lib.

find_library(libnet NAMES net libnet PATHS <wherever you built it to>)
include_directories(<wherever you built it to>/include)
target_link_libraries(test libnet)

CMake предоставляет достойный способ автоматизировать это с помощью ExternalProject_Add, Это немного сложнее в использовании, но вы можете загрузить, распаковать, собрать и установить libnet одной командой. Похоже, что libnet имеет несколько разных способов построения, в зависимости от платформы, поэтому это может быть не так просто.

Другой вариант - включить исходники libnet в ваш собственный проект и добавить его в виде библиотеки через add_library, Вам нужно создать список исходных кодов libnet, а также изучить make-файлы libnet, чтобы проверить наличие флагов / странностей компилятора, которые потребуют специальной обработки в вашем собственном CMakeLists.txt.

Это, пожалуй, лучший вариант, поскольку он дает вам доступ к полному дереву исходных текстов libnet в вашей IDE, позволяет точно настроить сборку libnet и приводит к тому, что ваш собственный проект устарел (требуется перестройка), если изменяется сборка libnet.,

set(LibnetSources <list all sources and headers>)
add_library(libnet ${LibnetSources})
include_directories(${PROJECT_SOURCE_DIR}/libnet/include)
target_link_libraries(test libnet)

Вы можете использовать file(GLOB...) чтобы помочь с генерацией списка источников libnet, но это не рекомендуется, так как CMake не будет автоматически обнаруживать добавление или удаление файла. Вы должны убедиться, что если вы сделаете это, вы повторно запустите cmake вручную, прежде чем пытаться перекомпилировать. Это не проблема, если вы не планируете добавлять / удалять любые файлы libnet.


Изменить: Использовать модуль ExternalProject

Хорошо, есть третий вариант, который может быть лучшим, но может быть немного сложным для настройки; использовать CMake ExternalProject Модуль Это предназначено для создания внешних зависимостей - даже тех, которые не используют CMake. Это достойная статья по его использованию.

Попробуйте заменить ваш CMakeLists.txt этим (проверено только на Ubuntu с gcc). Короче говоря, он загружает libnet, настраивает его, собирает и устанавливает в дерево сборки (не в /usr/local). Ваш исполняемый файл может включать и ссылаться на него.

# Minimum version 2.8.5 since we need ExternalProject module
cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR)
project(test)

# Enable ExternalProject CMake module
include(ExternalProject)

# Set default ExternalProject root directory
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/ThirdParty)

# Add libnet
ExternalProject_Add(
    libnet
    URL http://packetfactory.openwall.net/libnet/dist/libnet.tar.gz
    TIMEOUT 30
    CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
    BUILD_IN_SOURCE ON
    # Wrap download, configure, build and install steps in a script to log output
    LOG_DOWNLOAD ON
    LOG_CONFIGURE ON
    LOG_BUILD ON
    LOG_INSTALL ON)

# Specify include dir
ExternalProject_Get_Property(libnet install_dir)
include_directories(${install_dir}/include)

# Add test executable target
add_executable(test main.c)

# Create dependency of test on libnet
add_dependencies(test libnet)

# Specify test's link libraries
target_link_libraries(test ${install_dir}/lib/libnet.a)
Другие вопросы по тегам