Question

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!

Was it helpful?

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top