Skip to contentSkip to conversation

libbpf: make sure bpf headers are c++ include-able

PATCH Superseded Stanislav Fomichev 4 participants 10 messages Nov 21, 2018

Subsystems (4)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 libbpf: make sure bpf headers are c++ include-able

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 2 files changed, 18 insertions(+)
tools/lib/bpf/bpf.h +9 -0
index 26a51538213c..9ea3aec82d8a 100644
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -128,4 +132,9 @@ LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
 LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
 				 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
 				 __u64 *probe_offset, __u64 *probe_addr);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_BPF_H */
tools/lib/bpf/libbpf.h +9 -0
index b1686a787102..74e57e041705 100644
@@ -16,6 +16,10 @@
 #include <sys/types.h>  // for size_t
 #include <linux/bpf.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -335,4 +339,9 @@ int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
 			libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie);
 int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
 			 libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_LIBBPF_H */
Signature · 1 line
2.19.1.1215.g8438c0b245-goog
#1 lore raw
Quoted 8 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++

Do you want to add tools/lib/bpf/btf.h as well? it has some functions which could be used outside libbpf as well.

tools/lib/bpf/bpf.h line 32

Quoted 13 lines
 2 files changed, 18 insertions(+)
tools/lib/bpf/bpf.h +3 -0
index 26a51538213c..9ea3aec82d8a 100644
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif

Some (but not all) __cplusplus extern wrappers wraps standard include as well like "#include <stdbool.h>", "#include <stddef.h>". probably does not matter here
since they may not have function prototype. But just want to point it out so you are aware of this and may double check.

Quoted 42 lines
tools/lib/bpf/bpf.h +6 -0
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -128,4 +132,9 @@ LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
 LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
                                 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
                                 __u64 *probe_offset, __u64 *probe_addr);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_BPF_H */
tools/lib/bpf/libbpf.h +9 -1
index b1686a787102..74e57e041705 100644
@@ -16,6 +16,10 @@
 #include <sys/types.h>  // for size_t
 #include <linux/bpf.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -335,4 +339,9 @@ int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
                        libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie);
 int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
                         libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_LIBBPF_H */
--

2.19.1.1215.g8438c0b245-goog

#2 lore raw
Quoted 5 lines · Y Song
Quoted 4 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

Quoted 7 lines
Quoted 4 lines
---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++

Do you want to add tools/lib/bpf/btf.h as well? it has some functions which could be used outside libbpf as well.

Sure, I can do that in v2.

Quoted 10 lines
Quoted 10 lines
 2 files changed, 18 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
Quoted 9 lines

tools/lib/bpf/bpf.h line 32

Quoted 3 lines
tools/lib/bpf/bpf.h +3 -0
+#ifdef __cplusplus
+extern "C" {
+#endif

Some (but not all) __cplusplus extern wrappers wraps standard include as well like "#include <stdbool.h>", "#include <stddef.h>". probably does not matter here
since they may not have function prototype. But just want to point it out so you are aware of this and may double check.

Standard headers should be safe, they are usually wrapped into __BEGIN_DECLS/__END_DECLS (which is extern "C" {}). For <linux/bpf.h> I don't think we need an extern, because it only defines enums/structs and not something we can link against (global vars/functions).

Quoted 42 lines
Quoted 42 lines
tools/lib/bpf/bpf.h +6 -0
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -128,4 +132,9 @@ LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
 LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
                                 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
                                 __u64 *probe_offset, __u64 *probe_addr);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_BPF_H */
tools/lib/bpf/libbpf.h +9 -1
index b1686a787102..74e57e041705 100644
@@ -16,6 +16,10 @@
 #include <sys/types.h>  // for size_t
 #include <linux/bpf.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -335,4 +339,9 @@ int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
                        libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie);
 int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
                         libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_LIBBPF_H */
--

2.19.1.1215.g8438c0b245-goog

#3 lore raw

PATCH v2 1/1 libbpf: make sure bpf headers are c++ include-able

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +9 -0
index 26a51538213c..9ea3aec82d8a 100644
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -128,4 +132,9 @@ LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
 LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
 				 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
 				 __u64 *probe_offset, __u64 *probe_addr);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_BPF_H */
tools/lib/bpf/btf.h +8 -0
index b77e7080f7e7..5f3d7de850fc 100644
@@ -6,6 +6,10 @@
 
 #include <linux/types.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -29,4 +33,8 @@ LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
 LIBBPF_API int btf__fd(const struct btf *btf);
 LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
 
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_BTF_H */
tools/lib/bpf/libbpf.h +9 -0
index b1686a787102..74e57e041705 100644
@@ -16,6 +16,10 @@
 #include <sys/types.h>  // for size_t
 #include <linux/bpf.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef LIBBPF_API
 #define LIBBPF_API __attribute__((visibility("default")))
 #endif
@@ -335,4 +339,9 @@ int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
 			libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie);
 int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
 			 libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* __LIBBPF_LIBBPF_H */
Signature · 1 line
2.19.1.1215.g8438c0b245-goog
Acked-by Yonghong Song on v2 1/1
#4 lore raw
Quoted 8 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

Quoted 5 lines
---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
Acked-by on v2 1/1
#5 lore raw
In reply to Stanislav Fomichev
Quoted 18 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644

tools/lib/bpf/bpf.h line 32

Quoted 6 lines
tools/lib/bpf/bpf.h +3 -0
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif

was wondering whether it's possible to make it testable. HOSTCXX is available, but I don't see much of the kernel tree using it...

#6 lore raw
Quoted 28 lines · Alexei Starovoitov
Quoted 18 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644

tools/lib/bpf/bpf.h line 32

Quoted 6 lines
tools/lib/bpf/bpf.h +3 -0
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
Quoted 3 lines

was wondering whether it's possible to make it testable. HOSTCXX is available, but I don't see much of the kernel tree using it...

By testable you mean compile some dummy c++ main and link against libbpf?

perf has something similar:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/util/c++/clang-test.cpp#n7

But they don't use Makefiles for that (there is USE_CXX feature test as well), so I'm not sure either :-/

#7 lore raw
Quoted 29 lines · Stanislav Fomichev
Quoted 28 lines · Alexei Starovoitov
Quoted 18 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644

tools/lib/bpf/bpf.h line 32

Quoted 6 lines
tools/lib/bpf/bpf.h +3 -0
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
Quoted 4 lines
Quoted 3 lines

was wondering whether it's possible to make it testable. HOSTCXX is available, but I don't see much of the kernel tree using it...

By testable you mean compile some dummy c++ main and link against libbpf?

yes. something like this.
to make sure that it keeps being functional and no one introduces 'int new' in some function argument list by accident.

#8 lore raw
Quoted 30 lines · Alexei Starovoitov
Quoted 29 lines · Stanislav Fomichev
Quoted 28 lines · Alexei Starovoitov
Quoted 18 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644

tools/lib/bpf/bpf.h line 32

Quoted 6 lines
tools/lib/bpf/bpf.h +3 -0
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
Quoted 8 lines
Quoted 4 lines
Quoted 3 lines

was wondering whether it's possible to make it testable. HOSTCXX is available, but I don't see much of the kernel tree using it...

By testable you mean compile some dummy c++ main and link against libbpf?

yes. something like this.
to make sure that it keeps being functional and no one introduces 'int new' in some function argument list by accident.

I tried something like the patch below, it does seem to work locally (building in the same directory, no cross-compile). Who would be the best to review that kind of stuff?

tools/lib/bpf/Makefile +8 -1
index 425b480bda75..4c0e58628aad 100644
@@ -66,7 +66,7 @@ ifndef VERBOSE
 endif
 
 FEATURE_USER = .libbpf
-FEATURE_TESTS = libelf libelf-mmap bpf reallocarray
+FEATURE_TESTS = libelf libelf-mmap bpf reallocarray cxx
 FEATURE_DISPLAY = libelf bpf
 
 INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
@@ -148,6 +148,10 @@ LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
 
 CMD_TARGETS = $(LIB_FILE)
 
+ifeq ($(feature-cxx), 1)
+	CMD_TARGETS += $(OUTPUT)test_libbpf
+endif
+
 TARGETS = $(CMD_TARGETS)
 
 all: fixdep all_cmd
@@ -175,6 +179,9 @@ $(OUTPUT)libbpf.so: $(BPF_IN)
 $(OUTPUT)libbpf.a: $(BPF_IN)
 	$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
 
+$(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a
+	$(QUIET_LINK)$(CXX) $^ -lelf -o $@
+
 define do_install
 	if [ ! -d '$(DESTDIR_SQ)$2' ]; then		\
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2';	\
#9 lore raw
Quoted 68 lines · Stanislav Fomichev
Quoted 30 lines · Alexei Starovoitov
Quoted 29 lines · Stanislav Fomichev
Quoted 28 lines · Alexei Starovoitov
Quoted 18 lines · Stanislav Fomichev

Wrap headers in extern "C", to turn off C++ mangling. This simplifies including libbpf in c++ and linking against it.

v2 changes:
* do the same for btf.h

---
 tools/lib/bpf/bpf.h    | 9 +++++++++
 tools/lib/bpf/btf.h    | 8 ++++++++
 tools/lib/bpf/libbpf.h | 9 +++++++++
 3 files changed, 26 insertions(+)
tools/lib/bpf/bpf.h +0 -0
index 26a51538213c..9ea3aec82d8a 100644

tools/lib/bpf/bpf.h line 32

Quoted 6 lines
tools/lib/bpf/bpf.h +3 -0
@@ -27,6 +27,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
Quoted 8 lines
Quoted 4 lines
Quoted 3 lines

was wondering whether it's possible to make it testable. HOSTCXX is available, but I don't see much of the kernel tree using it...

By testable you mean compile some dummy c++ main and link against libbpf?

yes. something like this.
to make sure that it keeps being functional and no one introduces 'int new' in some function argument list by accident.

I tried something like the patch below, it does seem to work locally (building in the same directory, no cross-compile). Who would be the best to review that kind of stuff?

tools/lib/bpf/Makefile +5 -1
index 425b480bda75..4c0e58628aad 100644
@@ -66,7 +66,7 @@ ifndef VERBOSE
 endif
 
 FEATURE_USER = .libbpf
-FEATURE_TESTS = libelf libelf-mmap bpf reallocarray
+FEATURE_TESTS = libelf libelf-mmap bpf reallocarray cxx
 FEATURE_DISPLAY = libelf bpf
 
 INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
@@ -148,6 +148,10 @@ LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
 
 CMD_TARGETS = $(LIB_FILE)
 
+ifeq ($(feature-cxx), 1)
+	CMD_TARGETS += $(OUTPUT)test_libbpf
+endif
+
 TARGETS = $(CMD_TARGETS)
 
 all: fixdep all_cmd

tools/lib/bpf/Makefile $(OUTPUT)libbpf.so: $(BPF_IN) · line 183

Quoted 5 lines
tools/lib/bpf/Makefile +2 -0
@@ -175,6 +179,9 @@ $(OUTPUT)libbpf.so: $(BPF_IN)
 $(OUTPUT)libbpf.a: $(BPF_IN)
 	$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
 
+$(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a
+	$(QUIET_LINK)$(CXX) $^ -lelf -o $@

looks good to me.
pls include test_libbpf.cpp and resubmit for bpf-next.