ccmakekdeveloplibnet

How to use libnet with cmake (and kdevelop)?


I am afraid the question I have might be stupid, but as I am new to kdevelop and cmake it is quite hard for me to understand how they work. The project I tried to set up uses the libnet 1.1 library. My Question is how do I get cmake to compile and link this library so I can use it properly?

Here is what I already tried:

PROJECT(test)

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

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

Thank you for your Help!


Solution

  • It looks like libnet does not use CMake itself, so you're going to have to build it separately or make it part of your own project.

    To build it separately, you have a couple of choices. You can build it (and install it if you want) and then use find_library to locate the actual libnet.a / libnet.lib file.

    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 provides a decent way to automate this through use of ExternalProject_Add. This is a little trickier to use, but you can make it download, extract, build and install libnet all in one command. It looks like libnet has several different ways of being built though, depending on platform, so this may not be too straightforward.

    Another option would be to include the libnet sources in your own project and add it as a library via add_library. You'd need to create a list of the libnet sources, and also examine the libnet makefiles to check for any compiler flags / oddities that would need special handling in your own CMakeLists.txt

    This is perhaps the best option since it gives you access to the full libnet source tree in your IDE, allows you to fine-tune the libnet build, and causes your own project to go out of date (need rebuilding) if the libnet build changes.

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

    You can make use of file(GLOB...) to help with generating the list of libnet sources, but it's not recommended since the addition or removal of a file would not be automatically detected by CMake. You need to make sure that if you do this, you re-run cmake manually before trying to recompile. This isn't an issue if you're not planning on adding/deleting any libnet files.


    Edit: Use ExternalProject Module

    OK, there is a third option which is maybe the best, but can be slightly complex to set up; use CMake's ExternalProject Module. This is designed to allow building of external dependencies - even ones which don't use CMake. This is a decent article on using it.

    Try replacing your CMakeLists.txt with this (only tested on Ubuntu with gcc). In short, it downloads libnet, configures it, builds it and installs it to your build tree (not to /usr/local). Your executable can then include and link to it.

    # 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)