【问题标题】:How to use libnet with cmake (and kdevelop)?如何将 libnet 与 cmake(和 kdevelop)一起使用?
【发布时间】:2013-01-19 15:33:42
【问题描述】:

恐怕我的问题可能很愚蠢,但由于我是 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)

感谢您的帮助!

【问题讨论】:

    标签: c cmake kdevelop 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 源列表,并检查 libnet makefile 以检查需要在您自己的 CMakeLists.txt 中进行特殊处理的任何编译器标志/怪事

    这可能是最好的选择,因为它使您可以访问 IDE 中的完整 libnet 源代码树,允许您微调 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 Module。这旨在允许构建外部依赖项——即使是不使用 CMake 的依赖项。这是decent article 使用它。

    尝试用这个替换你的 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)
    

    【讨论】:

    • 首先感谢您的帮助!只有一件事我不明白,除了标题我还需要初始化哪些来源?
    • 如果您没有将 libnet 构建为您自己项目的一部分(上面的选项 1),那么它只是您需要的 libnet 标头。如果您将 libnet 源代码构建为您自己项目的一部分,那么您只需要它,在这种情况下,您将需要 all libnet 标头和源代码。您可能只需要列出所有 libnet 文件并执行add_library - 但是查看现有的 libnet makefile 将让您查看是否有任何文件需要排除/特殊处理/等等。
    • 抱歉这么晚才回答,但我之前从未使用过 set() 命令。语法是什么样的?我找不到显示如何引用文件地址的文档。
    • set 的语法是 set(&lt;variable&gt; &lt;value1&gt; ... &lt;valueN&gt;)(即空格分隔的列表)。在这种情况下,value1valueN 只是文件的路径。路径可以与您的 CMakeLists.txt 相关,理想情况下应使用正斜杠 / 作为路径分隔符,如果路径包含空格,则每个路径都需要用引号括起来。例如set(LibnetSources libnet/dir1/file1.cpp libnet/dir1/file1.h libnet/dir1/file2.cpp etc.)
    • 请注意,如果您选择使用file(GLOB...),则不需要使用set 命令(根据我在答案中的最后一段)。
    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2022-01-24
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    相关资源
    最近更新 更多