DPDK patches and discussions
 help / color / mirror / Atom feed
From: David Marchand <david.marchand@redhat.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, bruce.richardson@intel.com,
	Aaron Conole <aconole@redhat.com>,
	Michael Santana <maicolgabriel@hotmail.com>
Subject: [RFC 6/6] buildtools: externally check exported headers
Date: Wed, 27 Nov 2024 12:26:16 +0100	[thread overview]
Message-ID: <20241127112617.1331125-7-david.marchand@redhat.com> (raw)
In-Reply-To: <20241127112617.1331125-1-david.marchand@redhat.com>

At the moment, the headers check (triggered via the check_includes meson
option) is run "internally", iow with compilation flags and include path
coming from the meson components.

One issue is that both internal and public headers are usually stored
in a single directory in the DPDK components.
If a lib/foo library exports a header rte_foo.h (iow rte_foo.h is part
of the headers list in lib/foo/meson.build) and this rte_foo.h includes
an internal header foo_internal.h, then the headers check won't detect
such an issue as rte_foo.h is compiled with -Ilib/foo.

Reimplement the headers check by inspecting (compiling) all DPDK headers
installed in a staging directory.
To identify the directory where DPDK headers are, this check relies on
pkg-config and skips EAL generic/ and internal/ headers.

The existing headers check (though less accurate) is kept as is,
as it provides a first level of check and may have existing users.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 .ci/linux-build.sh            |  7 ++--
 buildtools/chkincs/Makefile   | 77 +++++++++++++++++++++++++++++++++++
 devtools/test-meson-builds.sh |  6 ++-
 3 files changed, 85 insertions(+), 5 deletions(-)
 create mode 100644 buildtools/chkincs/Makefile

diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
index fdb5787621..3146d9ccd8 100755
--- a/.ci/linux-build.sh
+++ b/.ci/linux-build.sh
@@ -95,8 +95,6 @@ OPTS="$OPTS -Ddefault_library=$DEF_LIB"
 OPTS="$OPTS -Dbuildtype=$buildtype"
 if [ "$STDATOMIC" = "true" ]; then
 	OPTS="$OPTS -Denable_stdatomic=true"
-else
-	OPTS="$OPTS -Dcheck_includes=true"
 fi
 if [ "$MINI" = "true" ]; then
     OPTS="$OPTS -Denable_drivers=net/null"
@@ -176,13 +174,16 @@ if [ "$RUN_TESTS" = "true" ]; then
     [ "$failed" != "true" ]
 fi
 
-# Test examples compilation with an installed dpdk
+# Test headers and examples compilation with an installed dpdk
 if [ "$BUILD_EXAMPLES" = "true" ]; then
     [ -d install ] || DESTDIR=$(pwd)/install meson install -C build
     export LD_LIBRARY_PATH=$(dirname $(find $(pwd)/install -name librte_eal.so)):$LD_LIBRARY_PATH
     export PATH=$(dirname $(find $(pwd)/install -name dpdk-devbind.py)):$PATH
     export PKG_CONFIG_PATH=$(dirname $(find $(pwd)/install -name libdpdk.pc)):$PKG_CONFIG_PATH
     export PKGCONF="pkg-config --define-prefix"
+
+    make -C buildtools/chkincs O=build/buildtools/chkincs
+
     find build/examples -maxdepth 1 -type f -name "dpdk-*" |
     while read target; do
         target=${target%%:*}
diff --git a/buildtools/chkincs/Makefile b/buildtools/chkincs/Makefile
new file mode 100644
index 0000000000..838819c617
--- /dev/null
+++ b/buildtools/chkincs/Makefile
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2024 Red Hat, Inc.
+
+ifeq ($(V),)
+Q ?= @
+else
+Q =
+endif
+
+O ?= build
+
+PKGCONF ?= pkg-config
+
+ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
+$(error "no installation of DPDK found")
+endif
+
+ifeq ($(I),)
+
+.PHONY: headers_list
+.ONESHELL:
+headers_list:
+	$(Q)for dir in $$($(PKGCONF) --cflags-only-I libdpdk); do
+		dir=$${dir##-I}
+		[ -e $$dir/rte_build_config.h ] || continue
+		$(MAKE) I="$$dir" O="$(O)"
+		break
+	done
+else
+
+HEADERS := $(shell find $(I) -name "*.h" | grep -vE $(I)'/(generic|internal)/')
+SRCS := $(patsubst $(I)/%.h, $(O)/%.c, $(HEADERS))
+.PRECIOUS: $(SRCS)
+
+PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
+CFLAGS = $(shell $(PKGCONF) --cflags libdpdk) -Wall -Wextra -Werror
+LDFLAGS = $(shell $(PKGCONF) --libs libdpdk)
+
+OBJS := $(patsubst $(I)/%.h, $(O)/%.o, $(HEADERS))
+OBJS_EXP := $(patsubst $(I)/%.h, $(O)/%+exp.o, $(HEADERS))
+OBJS_ALL := $(patsubst $(I)/%.h, $(O)/%+all.o, $(HEADERS))
+
+all: $(OBJS) $(OBJS_EXP) $(OBJS_ALL)
+
+$(O):
+	$(Q)mkdir -p $@
+
+$(O)/%.c: $(I)/%.h $(O) gen_c_file_for_header.py Makefile
+	$(Q)python3 gen_c_file_for_header.py $< $@
+
+$(O)/%.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CC) $(CFLAGS) -o $@ -c $<
+
+$(O)/%+exp.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CC) $(CFLAGS) -DALLOW_EXPERIMENTAL_API -o $@ -c $<
+
+$(O)/%+all.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CC) $(CFLAGS) -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -o $@ -c $<
+
+CXXFLAGS = $(shell $(PKGCONF) --cflags libdpdk) -Wall -Wextra -Werror
+
+OBJS_CPP := $(patsubst $(I)/%.h, $(O)/%.cpp.o, $(HEADERS))
+OBJS_CPP_EXP := $(patsubst $(I)/%.h, $(O)/%.cpp+exp.o, $(HEADERS))
+OBJS_CPP_ALL := $(patsubst $(I)/%.h, $(O)/%.cpp+all.o, $(HEADERS))
+
+all: $(OBJS_CPP) $(OBJS_CPP_EXP) $(OBJS_CPP_ALL)
+
+$(O)/%.cpp.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CXX) $(CXXFLAGS) -o $@ -c $<
+
+$(O)/%.cpp+exp.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CXX) $(CXXFLAGS) -DALLOW_EXPERIMENTAL_API -o $@ -c $<
+
+$(O)/%.cpp+all.o: $(O)/%.c Makefile $(PC_FILE)
+	$(Q)$(CXX) $(CXXFLAGS) -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -o $@ -c $<
+
+endif
diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh
index 4fff1f7177..c3cebead70 100755
--- a/devtools/test-meson-builds.sh
+++ b/devtools/test-meson-builds.sh
@@ -248,7 +248,7 @@ generic_isa='nehalem'
 if ! check_cc_flags "-march=$generic_isa" ; then
 	generic_isa='corei7'
 fi
-build build-x86-generic cc skipABI -Dcheck_includes=true \
+build build-x86-generic cc skipABI \
 	-Dlibdir=lib -Dcpu_instruction_set=$generic_isa $use_shared
 
 # 32-bit with default compiler
@@ -318,9 +318,11 @@ if [ "$examples" = 'all' ]; then
 	done | sort -u |
 	tr '\n' ' ')
 fi
-# if pkg-config defines the necessary flags, test building some examples
+# if pkg-config defines the necessary flags, check headers and test building some examples
 if pkg-config --define-prefix libdpdk >/dev/null 2>&1; then
 	export PKGCONF="pkg-config --define-prefix"
+	echo "## Checking exported headers"
+	$MAKE -C buildtools/chkincs O=$build_path/buildtools/chkincs -j
 	for example in $examples; do
 		echo "## Building $example"
 		[ $example = helloworld ] && static=static || static= # save disk space
-- 
2.47.0


      parent reply	other threads:[~2024-11-27 11:27 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-27 11:26 [RFC 0/6] Add a stricter headers check David Marchand
2024-11-27 11:26 ` [RFC 1/6] baseband/acc: fix exported header David Marchand
2024-11-27 11:26 ` [RFC 2/6] drivers: drop export of driver headers David Marchand
2024-11-27 11:26 ` [RFC 3/6] eventdev: do not include driver header in DMA adapter David Marchand
2024-11-27 13:49   ` [EXTERNAL] " Amit Prakash Shukla
2024-11-27 11:26 ` [RFC 4/6] drivers: fix exported headers David Marchand
2024-11-27 11:26 ` [RFC 5/6] build: install indirect headers to a dedicated directory David Marchand
2024-11-27 11:42   ` Bruce Richardson
2024-11-27 11:26 ` David Marchand [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241127112617.1331125-7-david.marchand@redhat.com \
    --to=david.marchand@redhat.com \
    --cc=aconole@redhat.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=maicolgabriel@hotmail.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).