From 49e30002194262651cfb8448a7c13f0fd1b31613 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Tue, 24 May 2022 13:36:16 +0100 Subject: [PATCH 1/3] build(openwrt): use single toolchain location Previously, the toolchain was being built in the CMAKE_BINARY_DIR. However, libpcap uses the command, `check_include_file()`, which creates a new CMake project in a temporary folder to test C/C++ features. This causes the OpenWRT SDK to be constantly downloaded multiple times, taking a lot of time. Instead, I've changed the OpenWRT toolchain file to download and extract the SDK next to the toolchain file. This should let the SDK be cached. --- CMakeModules/CMakeToolchains/.gitignore | 2 ++ CMakeModules/CMakeToolchains/openwrt-mvebu-cortexa9.cmake | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 CMakeModules/CMakeToolchains/.gitignore diff --git a/CMakeModules/CMakeToolchains/.gitignore b/CMakeModules/CMakeToolchains/.gitignore new file mode 100644 index 000000000..a4ccd556c --- /dev/null +++ b/CMakeModules/CMakeToolchains/.gitignore @@ -0,0 +1,2 @@ +# ignore toolchains downloaded by FetchContent +/build diff --git a/CMakeModules/CMakeToolchains/openwrt-mvebu-cortexa9.cmake b/CMakeModules/CMakeToolchains/openwrt-mvebu-cortexa9.cmake index 768713255..b6ffcef28 100644 --- a/CMakeModules/CMakeToolchains/openwrt-mvebu-cortexa9.cmake +++ b/CMakeModules/CMakeToolchains/openwrt-mvebu-cortexa9.cmake @@ -16,6 +16,9 @@ if(NOT DEFINED openwrt_toolchain_location) URL https://downloads.openwrt.org/releases/19.07.10/targets/mvebu/cortexa9/openwrt-sdk-19.07.10-mvebu-cortexa9_gcc-7.5.0_musl_eabi.Linux-x86_64.tar.xz # sha256 from https://downloads.openwrt.org/releases/19.07.10/targets/mvebu/cortexa9/sha256sums URL_HASH SHA256=17941f42e26d3c54a836f9897e78abaafcf66e5f0b28ffd8956378aa69c3a4d9 + # Make sure that that the toolchain location is indepent from CMAKE_BINARY_DIR/CMAKE_SOURCE_DIR + # otherwise `check_include_file()` commands will redownload these files slowly + PREFIX "${CMAKE_CURRENT_LIST_DIR}/build/openwrt_sdk_mvebu_cortexa9" ) FetchContent_Populate(openwrt_sdk_mvebu_cortexa9) set( From 6e6cefdee7e345432570eca02c5cc9b14338a771 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Tue, 24 May 2022 09:53:15 +0100 Subject: [PATCH 2/3] build: remove `${LIBPCAP_INCLUDE_PATH}` in cmake Manually setting LIBPCAP_INCLUDE_PATH is not needed, as target_link_libraries(... PCAP::pcap) will automatically include it when needed. --- src/CMakeLists.txt | 6 +++--- src/capture/CMakeLists.txt | 26 ++++++++++---------------- src/dns/CMakeLists.txt | 1 - tests/capture/CMakeLists.txt | 6 ++---- tests/dns/CMakeLists.txt | 3 +-- 5 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bd43df3b8..033433fdf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,15 +30,15 @@ target_link_libraries(config PRIVATE minIni os log) if (BUILD_MDNS_SERVICE AND BUILD_CAPTURE_SERVICE) add_executable(mdnsf mdnsf.c) - target_include_directories(mdnsf PRIVATE ${LIBPCAP_INCLUDE_PATH} ${PROJECT_BINARY_DIR} ${LIBSQLITE_INCLUDE_DIR}) - target_link_libraries(mdnsf PRIVATE mdns_service config minIni squeue iface_mapper log os) + target_include_directories(mdnsf PRIVATE ${PROJECT_BINARY_DIR} ${LIBSQLITE_INCLUDE_DIR}) + target_link_libraries(mdnsf PRIVATE mdns_service config minIni squeue iface_mapper log os PCAP::pcap) # link time optimization set_target_properties(mdnsf PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) endif () if (BUILD_CAPTURE_SERVICE) add_executable(capsrv capsrv.c) - target_include_directories(capsrv PRIVATE ${LIBPCAP_INCLUDE_PATH} ${PROJECT_BINARY_DIR} ${LIBSQLITE_INCLUDE_DIR}) + target_include_directories(capsrv PRIVATE ${PROJECT_BINARY_DIR} ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(capsrv capture_service capture_config config minIni os hashmap PCAP::pcap) # link time optimization set_target_properties(capsrv PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) diff --git a/src/capture/CMakeLists.txt b/src/capture/CMakeLists.txt index 4f210d0fc..d24b6b505 100644 --- a/src/capture/CMakeLists.txt +++ b/src/capture/CMakeLists.txt @@ -13,52 +13,46 @@ if (BUILD_CAPTURE_SERVICE) target_link_libraries(mdns_decoder PRIVATE squeue log os hash PUBLIC packet_decoder) add_library(dns_decoder dns_decoder.c) - target_include_directories(dns_decoder PRIVATE ${LIBPCAP_INCLUDE_PATH}) - target_link_libraries(dns_decoder PRIVATE log os hash) + target_link_libraries(dns_decoder PRIVATE log os hash packet_decoder) add_library(packet_decoder packet_decoder.c) # packet_decoder.h has an #include , so need to make it PUBLIC include - target_include_directories(packet_decoder PUBLIC ${LIBPCAP_INCLUDE_PATH}) target_link_libraries(packet_decoder PUBLIC PCAP::pcap PRIVATE mdns_decoder dns_decoder hash net log os hashmap) add_library(packet_queue packet_queue.c) - target_link_libraries(packet_queue PRIVATE packet_decoder log os) + target_link_libraries(packet_queue PUBLIC packet_decoder PRIVATE log os) add_library(pcap_service pcap_service.c) - - target_include_directories(pcap_service PRIVATE ${LIBPCAP_INCLUDE_PATH}) - target_link_libraries(pcap_service PRIVATE net log os PCAP::pcap) + target_link_libraries(pcap_service PUBLIC PCAP::pcap PRIVATE net log os) add_library(pcap_queue pcap_queue.c) - target_include_directories(pcap_queue PRIVATE ${LIBPCAP_INCLUDE_PATH}) - target_link_libraries(pcap_queue PRIVATE log os) + target_link_libraries(pcap_queue PUBLIC PCAP::pcap PRIVATE log os) add_library(sqlite_header_writer sqlite_header_writer.c) - target_include_directories(sqlite_header_writer PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) - target_link_libraries(sqlite_header_writer PRIVATE sqliteu squeue log os iface SQLite::sqlite) + target_include_directories(sqlite_header_writer PRIVATE ${LIBSQLITE_INCLUDE_DIR}) + target_link_libraries(sqlite_header_writer PRIVATE sqliteu squeue log os iface SQLite::sqlite packet_decoder) add_library(sqlite_pcap_writer sqlite_pcap_writer.c) - target_include_directories(sqlite_pcap_writer PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) + target_include_directories(sqlite_pcap_writer PRIVATE ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(sqlite_pcap_writer PRIVATE sqliteu log os SQLite::sqlite) add_library(default_analyser default_analyser.c) - - target_include_directories(default_analyser PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) + target_include_directories(default_analyser PRIVATE ${LIBSQLITE_INCLUDE_DIR}) add_library(capture_cleaner capture_cleaner.c) target_include_directories(capture_cleaner PRIVATE ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(capture_cleaner PRIVATE sqlite_pcap_writer eloop log os SQLite::sqlite) - target_link_libraries(default_analyser PRIVATE dns_decoder pcap_service sqlite_header_writer sqlite_pcap_writer pcap_queue packet_queue packet_decoder squeue eloop iface log os hashmap domain) + target_link_libraries(default_analyser PUBLIC PCAP::pcap PRIVATE dns_decoder pcap_service sqlite_header_writer sqlite_pcap_writer pcap_queue packet_queue packet_decoder squeue eloop iface log os hashmap domain) add_library(capture_service capture_service.c) - target_include_directories(capture_service PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) + target_include_directories(capture_service PRIVATE ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(capture_service PRIVATE capture_cleaner default_analyser log) endif() diff --git a/src/dns/CMakeLists.txt b/src/dns/CMakeLists.txt index fc09d095c..303b46097 100644 --- a/src/dns/CMakeLists.txt +++ b/src/dns/CMakeLists.txt @@ -9,7 +9,6 @@ add_library(mdns_list mdns_list.c) target_link_libraries(mdns_list PRIVATE os) add_library(mdns_mapper mdns_mapper.c) -target_include_directories(mdns_mapper PRIVATE ${LIBPCAP_INCLUDE_PATH}) target_link_libraries(mdns_mapper PRIVATE mdns_list os) add_library(mcast mcast.c) diff --git a/tests/capture/CMakeLists.txt b/tests/capture/CMakeLists.txt index cc730c5f0..fb75938cd 100644 --- a/tests/capture/CMakeLists.txt +++ b/tests/capture/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories ( ) add_executable(test_default_analyser test_default_analyser.c) -target_include_directories(test_default_analyser PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) +target_include_directories(test_default_analyser PRIVATE ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(test_default_analyser PRIVATE default_analyser packet_queue os log cmocka::cmocka) set_target_properties(test_default_analyser PROPERTIES @@ -11,11 +11,9 @@ set_target_properties(test_default_analyser ) add_executable(test_packet_queue test_packet_queue.c) -target_include_directories(test_packet_queue PRIVATE ${LIBPCAP_INCLUDE_PATH}) target_link_libraries(test_packet_queue PRIVATE packet_queue os log cmocka::cmocka) add_executable(test_pcap_queue test_pcap_queue.c) -target_include_directories(test_pcap_queue PRIVATE ${LIBPCAP_INCLUDE_PATH}) target_link_libraries(test_pcap_queue PRIVATE pcap_queue os log cmocka::cmocka) add_executable(test_capture_config test_capture_config.c) @@ -26,7 +24,7 @@ target_include_directories(test_sqlite_pcap_writer PRIVATE ${LIBSQLITE_INCLUDE_D target_link_libraries(test_sqlite_pcap_writer PRIVATE sqlite_pcap_writer sqliteu os log cmocka::cmocka) add_executable(test_sqlite_header_writer test_sqlite_header_writer.c) -target_include_directories(test_sqlite_header_writer PRIVATE ${LIBPCAP_INCLUDE_PATH} ${LIBSQLITE_INCLUDE_DIR}) +target_include_directories(test_sqlite_header_writer PRIVATE ${LIBSQLITE_INCLUDE_DIR}) target_link_libraries(test_sqlite_header_writer PRIVATE sqlite_header_writer sqliteu os log cmocka::cmocka) set_target_properties(test_sqlite_header_writer PROPERTIES diff --git a/tests/dns/CMakeLists.txt b/tests/dns/CMakeLists.txt index f0c5a203f..d3cf82ee0 100644 --- a/tests/dns/CMakeLists.txt +++ b/tests/dns/CMakeLists.txt @@ -16,12 +16,11 @@ target_link_libraries(test_reflection_list PRIVATE reflection_list log cmocka::c if (BUILD_MDNS_SERVICE AND BUILD_CAPTURE_SERVICE) add_executable(test_mdns_service test_mdns_service.c) - target_link_libraries(test_mdns_service PRIVATE mdns_service log cmocka::cmocka) + target_link_libraries(test_mdns_service PRIVATE mdns_service pcap_service log cmocka::cmocka) set_target_properties(test_mdns_service PROPERTIES LINK_FLAGS "-Wl,--wrap=run_pcap -Wl,--wrap=eloop_register_read_sock -Wl,--wrap=eloop_init -Wl,--wrap=eloop_destroy -Wl,--wrap=eloop_run" ) - target_include_directories(test_mdns_service PRIVATE ${LIBPCAP_INCLUDE_PATH}) endif () add_test(NAME test_mdns_list COMMAND test_mdns_list) From a1a806b3e0f9fc0e3b31dc47f55c74807a99d59c Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Tue, 24 May 2022 10:51:34 +0100 Subject: [PATCH 3/3] build(pcap): compile `libpcap` at compile time We use `FetchContent_MakeAvailable(libpcap)` to compile libpcap at compile time. Additionally, we only compile `pcap_static`, and nothing else. Since this is a static library, we also don't need to include it in `cmake --install`. --- CMakeLists.txt | 3 +++ lib/pcap.cmake | 69 +++++++++++++++++--------------------------------- 2 files changed, 26 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f99aca6bd..bed3fef7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,9 @@ else(CMAKE_CROSSCOMPILING) unset(target_autoconf_triple) endif(CMAKE_CROSSCOMPILING) +# currenty doesn't work if on, due to cyclical dependencies +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Build shared libraries") + # C compiler options set(CMAKE_C_STANDARD 11) # we use C11 raw-strings set(CMAKE_C_STANDARD_REQUIRED TRUE) diff --git a/lib/pcap.cmake b/lib/pcap.cmake index 1b0fb9e06..95a053efc 100644 --- a/lib/pcap.cmake +++ b/lib/pcap.cmake @@ -1,53 +1,30 @@ if (BUILD_PCAP_LIB AND NOT (BUILD_ONLY_DOCS)) add_compile_definitions(WITH_PCAP_SERVICE) - set(LIBPCAP_INSTALL_ROOT ${CMAKE_CURRENT_BINARY_DIR}/lib) - set(LIBPCAP_INSTALL_DIR ${LIBPCAP_INSTALL_ROOT}/pcap) - set(LIBPCAP_INCLUDE_PATH ${LIBPCAP_INSTALL_DIR}/include) - set(LIBPCAP_LIB_DIR "${LIBPCAP_INSTALL_DIR}/lib") - find_library(LIBPCAP_LIB NAMES libpcap.a pcap PATHS "${LIBPCAP_LIB_DIR}" NO_DEFAULT_PATH) - if (LIBPCAP_LIB) - message("Found libpcap library: ${LIBPCAP_LIB}") - ELSE () - FetchContent_Declare( - libpcap - URL https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/libpcap-1.10.1.tar.gz - URL_HASH SHA3_256=9aedcbec09b7b3b01c78cc80822c505846d73928a72ae96eb907b1f467eee649 - ) - FetchContent_Populate(libpcap) - execute_process(COMMAND ${CMAKE_COMMAND} - -B build/ -S "${libpcap_SOURCE_DIR}" - "-DCMAKE_INSTALL_PREFIX=${LIBPCAP_INSTALL_DIR}" - # Pass C/CXX compiler for gcc/cross-compiling - "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" - "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - # Disable DBUS support (otherwise need to link dbus-1 when static linking) - -DDISABLE_DBUS=ON - # Disable RDMA support (otherwise need to link ibverbs when static linking) - -DDISABLE_RDMA=ON - # Disable libnl support (otherwise need to link nl-3 when static linking) - -DBUILD_WITH_LIBNL=OFF - WORKING_DIRECTORY "${libpcap_BINARY_DIR}" - ) - execute_process(COMMAND ${CMAKE_COMMAND} - --build build/ - WORKING_DIRECTORY "${libpcap_BINARY_DIR}" - ) - execute_process(COMMAND ${CMAKE_COMMAND} - --install build/ - WORKING_DIRECTORY "${libpcap_BINARY_DIR}" - ) + FetchContent_Declare( + libpcap + URL https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/libpcap-1.10.1.tar.gz + URL_HASH SHA3_256=9aedcbec09b7b3b01c78cc80822c505846d73928a72ae96eb907b1f467eee649 + ) - find_library(LIBPCAP_LIB NAMES libpcap.a pcap PATHS "${LIBPCAP_LIB_DIR}" NO_DEFAULT_PATH) - endif () + set(DISABLE_DBUS ON CACHE BOOL "Disable DBUS support (otherwise need to link dbus-1 when static linking)" FORCE) + set(DISABLE_RDMA ON CACHE BOOL "Disable RDMA support (otherwise need to link ibverbs when static linking)" FORCE) + set(BUILD_WITH_LIBNL OFF CACHE BOOL "Disable libnl support (otherwise need to link nl-3 when static linking)" FORCE) - if (NOT TARGET PCAP::pcap) - add_library(PCAP::pcap UNKNOWN IMPORTED) + # create static lib using -fPIC, so we can make it into a sharedobject later + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + # declares the `pcap_static` target + FetchContent_MakeAvailable(libpcap) - set_target_properties(PCAP::pcap PROPERTIES - IMPORTED_LOCATION "${LIBPCAP_LIB}" - # Check ./build/lib/pcap/lib/pkgconfig for linker dependencies - INTERFACE_INCLUDE_DIRECTORIES "${LIBPCAP_INCLUDE_PATH}" - ) - endif(NOT TARGET PCAP::pcap) + # skip installing `libpcap` when running `make install` + # we're compiling `libpcap` statically, so it's not needed + # work around until https://gitlab.kitware.com/cmake/cmake/-/issues/20167 is fixed + if(IS_DIRECTORY "${libpcap_SOURCE_DIR}") + set_property(DIRECTORY ${libpcap_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL YES) + endif() + + # pcap_static does not declare include_directories, so we need to manually add them + add_library(PCAP::pcap INTERFACE IMPORTED) + target_link_libraries(PCAP::pcap INTERFACE pcap_static) + target_include_directories(PCAP::pcap INTERFACE "${libpcap_SOURCE_DIR}") endif ()