@cryptotaxi247 / netdata-1 / commits / 5539e60f4

Clean up handling of compiler flags in our build code. (#20821)

* Consolidate compiler flag handling as much as possible. Instead of relying on compiler flags being set correctly in our build environments by the build scripts, set them appropriately in our CMake code. Also, move as much of our compiler flag handling within the CMake code as possible into the NetdataCompilerFlags module. * General cleanup of compiler flag handling. * Make CMake option for static builds more explicit. * Fix function invocations. * Fix ASAN flag. * Fix protobuf handling for RPM package builds. * Further fix protobuf handling.

Austin S. Hemmelgarn committed Oct 1, 2025 at 07:08 UTC 5539e60f45bf2edfff5686205589987a8e182eab
8 files changed +99 -103
CMakeLists.txt
+5 -12
@@ -20,15 +20,13 @@ include(CMakeDependentOption)
20 include(NetdataUtil)
21 netdata_fixup_system_processor()
22
23 -if(DEFINED BUILD_SHARED_LIBS)
24 - if(NOT BUILD_SHARED_LIBS)
25 - set(STATIC_BUILD TRUE)
26 - endif()
27 -endif()
23 +option(STATIC_BUILD "Use static linking instead of dynamic linking for the build." FALSE)
24 +mark_as_advanced(STATIC_BUILD)
25 +set(BUILD_SHARED_LIBS "${STATIC_BUILD}")
26
27 if(STATIC_BUILD)
30 - set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_STATIC_LIBRARY_PREFIX}")
31 - set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}")
28 + set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_STATIC_LIBRARY_PREFIX}")
29 + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}")
30 endif()
31
32 find_package(PkgConfig REQUIRED)
@@ -171,11 +169,6 @@ set(WEB_DIR "${NETDATA_RUNTIME_PREFIX}/${WEB_DEST}")
169
170 include(NetdataCompilerFlags)
171
174 -check_c_compiler_flag("-fexceptions" HAVE_FEXCEPTIONS)
175 -if (NOT HAVE_FEXCEPTIONS)
176 - message(FATAL_ERROR "Missing required compiler flag: -fexceptions.")
177 -endif()
178 -
172 # This is intended to make life easier for developers who are working on one
173 # specific feature.
174 #
netdata.spec.in
+3
@@ -47,6 +47,8 @@ AutoReqProv: yes
47 %global _have_ebpf 0
48 %endif
49
50 +%global _original_libdir %{_libdir}
51 +
52 # Mitigate the cross-distro mayhem by strictly defining the libexec destination
53 %define _prefix /usr
54 %define _sysconfdir /etc
@@ -354,6 +356,7 @@ advanced correlations and fast root cause analysis, native horizontal scalabilit
356 %if 0%{?suse_version}
357 -DUSE_LTO=Off \
358 %endif
359 + -DProtobuf_LIBRARY=%{_original_libdir}/libprotobuf.so \
360 %if %{_have_cups}
361 -DENABLE_PLUGIN_CUPS=On \
362 %else
packaging/cmake/Modules/NetdataCompilerFlags.cmake
+55 -58
@@ -9,69 +9,61 @@ include(CheckCXXCompilerFlag)
9 # This takes a specified value, and assigns the generated name to the
10 # specified target.
11 function(make_cpp_safe_name value target)
12 - string(REPLACE "-" "_" tmp "${value}")
13 - string(REPLACE "=" "_" tmp "${tmp}")
14 - set(${target} "${tmp}" PARENT_SCOPE)
12 + string(REPLACE "-" "_" tmp "${value}")
13 + string(REPLACE "=" "_" tmp "${tmp}")
14 + set(${target} "${tmp}" PARENT_SCOPE)
15 endfunction()
16
17 # Conditionally add an extra compiler flag to C and C++ flags.
18 #
19 # If the language flags already match the `match` argument, skip this flag.
20 # Otherwise, check for support for `flag` and if support is found, add it to
21 -# the compiler flags for the run.
22 -function(add_simple_extra_compiler_flag match flag)
23 - set(CMAKE_REQUIRED_FLAGS "-Werror")
21 +# the compiler flags for the run. Also sets `result` to MATCHED/ADDED/UNSUPPORTED
22 +# depending on whether the flag was added or not.
23 +function(add_extra_compiler_flag match flag result)
24 + set(CMAKE_REQUIRED_FLAGS "-Werror")
25
25 - make_cpp_safe_name("${flag}" flag_name)
26 + make_cpp_safe_name("${flag}" flag_name)
27
27 - if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
28 - check_c_compiler_flag("${flag}" HAVE_C_${flag_name})
29 - endif()
28 + if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
29 + check_c_compiler_flag("${flag}" HAVE_C_${flag_name})
30 + else()
31 + set(matched_c TRUE)
32 + endif()
33
31 - if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
32 - check_cxx_compiler_flag("${flag}" HAVE_CXX_${flag_name})
33 - endif()
34 + if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
35 + check_cxx_compiler_flag("${flag}" HAVE_CXX_${flag_name})
36 + else()
37 + set(matched_cxx TRUE)
38 + endif()
39
35 - if(HAVE_C_${flag_name} AND HAVE_CXX_${flag_name})
36 - add_compile_options("${flag}")
37 - add_link_options("${flag}")
38 - endif()
40 + if(HAVE_C_${flag_name} AND HAVE_CXX_${flag_name})
41 + add_compile_options("${flag}")
42 + add_link_options("${flag}")
43 + set(${result} ADDED PARENT_SCOPE)
44 + elseif(matched_c OR matched_cxx)
45 + set(${result} MATCHED PARENT_SCOPE)
46 + else()
47 + set(${result} UNSUPPORTED PARENT_SCOPE)
48 + endif()
49 endfunction()
50
51 # Same as add_simple_extra_compiler_flag, but check for a second flag if the
52 # first one is unsupported.
43 -function(add_double_extra_compiler_flag match flag1 flag2)
44 - set(CMAKE_REQUIRED_FLAGS "-Werror")
45 -
46 - make_cpp_safe_name("${flag1}" flag1_name)
47 - make_cpp_safe_name("${flag2}" flag2_name)
48 -
49 - if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
50 - check_c_compiler_flag("${flag1}" HAVE_C_${flag1_name})
51 - if(NOT HAVE_C_${flag1_name})
52 - check_c_compiler_flag("${flag2}" HAVE_C_${flag2_name})
53 - endif()
54 - endif()
55 -
56 - if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
57 - check_cxx_compiler_flag("${flag1}" HAVE_CXX_${flag1_name})
58 - if(NOT HAVE_CXX_${flag1_name})
59 - check_cxx_compiler_flag("${flag2}" HAVE_CXX_${flag2_name})
60 - endif()
61 - endif()
62 -
63 - if(HAVE_C_${flag1_name} AND HAVE_CXX_${flag1_name})
64 - add_compile_options("${flag1}")
65 - add_link_options("${flag1}")
66 - elseif(HAVE_C_${flag2_name} AND HAVE_CXX${flag2_name})
67 - add_compile_options("${flag2}")
68 - add_link_options("${flag2}")
69 - endif()
53 +function(add_double_extra_compiler_flag match flag1 flag2 result)
54 + add_extra_compiler_flag("${match}" "${flag1}" flag1_success)
55 +
56 + if(${flag1_success} STREQUAL UNSUPPORTED)
57 + add_extra_compiler_flag("${match}" "${flag2}" flag2_success)
58 + set(${result} "${flag2_success}" PARENT_SCOPE)
59 + else()
60 + set(${result} "${flag1_success}" PARENT_SCOPE)
61 + endif()
62 endfunction()
63
64 # Add a required extra compiler flag to C and C++ flags.
65 #
74 -# Similar logic as add_simple_extra_compiler_flag, but ignores existing
66 +# Similar logic to add_extra_compiler_flag, but ignores existing
67 # instances and throws an error if the flag is not supported.
68 function(add_required_compiler_flag flag)
69 set(CMAKE_REQUIRED_FLAGS "-Werror")
@@ -99,18 +91,24 @@ else()
91 endif()
92
93 if(CMAKE_BUILD_TYPE STREQUAL "Debug")
102 - option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" TRUE)
103 - option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." FALSE)
94 + option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" TRUE)
95 + option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." FALSE)
96 else()
105 - option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" FALSE)
106 - option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." TRUE)
97 + option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" FALSE)
98 + option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." TRUE)
99 endif()
100
101 option(ENABLE_ADDRESS_SANITIZER "Build with address sanitizer enabled" False)
102 mark_as_advanced(ENABLE_ADDRESS_SANITIZER)
103
104 if(ENABLE_ADDRESS_SANITIZER)
113 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
105 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
106 +endif()
107 +
108 +if(STATIC_BUILD)
109 + add_required_compiler_flag("-static")
110 +
111 + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
112 endif()
113
114 if(USE_LTO)
@@ -138,16 +136,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}")
136 add_required_compiler_flag("-fexceptions")
137
138 if(NOT ${DISABLE_HARDENING})
141 - add_double_extra_compiler_flag("stack-protector" "-fstack-protector-strong" "-fstack-protector")
142 - add_double_extra_compiler_flag("_FORTIFY_SOURCE" "-D_FORTIFY_SOURCE=3" "-D_FORTIFY_SOURCE=2")
143 - add_simple_extra_compiler_flag("stack-clash-protection" "-fstack-clash-protection")
144 - add_simple_extra_compiler_flag("-fcf-protection" "-fcf-protection=full")
145 - add_simple_extra_compiler_flag("branch-protection" "-mbranch-protection=standard")
139 + add_double_extra_compiler_flag("stack-protector" "-fstack-protector-strong" "-fstack-protector" HAVE_STACK_PROTECTOR)
140 + add_double_extra_compiler_flag("_FORTIFY_SOURCE" "-D_FORTIFY_SOURCE=3" "-D_FORTIFY_SOURCE=2" HAVE_FORTIFY_SOURCE)
141 + add_extra_compiler_flag("stack-clash-protection" "-fstack-clash-protection" HAVE_STACK_CLASH_PROTECTION)
142 + add_extra_compiler_flag("-fcf-protection" "-fcf-protection=full" HAVE_CFI)
143 + add_extra_compiler_flag("branch-protection" "-mbranch-protection=standard" HAVE_BRANCH_PROTECTION)
144 endif()
145
146 foreach(FLAG function-sections data-sections)
149 - add_simple_extra_compiler_flag("${FLAG}" "-f${FLAG}")
147 + add_extra_compiler_flag("${FLAG}" "-f${FLAG}" HAVE_${FLAG})
148 endforeach()
149
152 -add_simple_extra_compiler_flag("-Wbuiltin-macro-redefined" "-Wno-builtin-macro-redefined")
153 -add_simple_extra_compiler_flag("-fexceptions" "-fexceptions")
150 +add_extra_compiler_flag("-Wbuiltin-macro-redefined" "-Wno-builtin-macro-redefined" HAVE_MACRO)
packaging/cmake/Modules/NetdataLibBPF.cmake
+2 -4
@@ -32,10 +32,8 @@ function(netdata_bundle_libbpf)
32 set(_libbpf_tag 5acba1722d66a25ad5a545f9296e59d0cb73d548) # v1.6.2p_netdata
33 endif()
34
35 - if(DEFINED BUILD_SHARED_LIBS)
36 - if(NOT BUILD_SHARED_LIBS)
37 - set(need_static TRUE)
38 - endif()
35 + if(STATIC_BUILD)
36 + set(need_static TRUE)
37 endif()
38
39 if(NOT need_static)
packaging/cmake/Modules/NetdataProtobuf.cmake
+21 -14
@@ -129,20 +129,27 @@ macro(netdata_detect_protobuf)
129 endif()
130
131 if(TARGET protobuf::libprotobuf)
132 - if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc)
133 - set(Protobuf_PROTOC_EXECUTABLE protobuf::protoc)
134 - endif()
135 -
136 - # It is technically possible that this may still not
137 - # be set by this point, so we need to check it and
138 - # fail noisily if it isn't because the build won't
139 - # work without it.
140 - if(NOT Protobuf_PROTOC_EXECUTABLE)
141 - message(FATAL_ERROR "Could not determine the location of the protobuf compiler for the detected version of protobuf.")
142 - endif()
143 -
144 - set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
145 - set(PROTOBUF_LIBRARIES protobuf::libprotobuf)
132 + get_property(IMPORTED_SET TARGET protobuf::libprotobuf PROPERTY IMPORTED_LOCATION SET)
133 + get_property(ALIASED TARGET protobuf::libprotobuf PROPERTY ALIASED_TARGET)
134 +
135 + if(ALIASED STREQUAL "" AND NOT IMPORTED_SET)
136 + set_property(TARGET protobuf::libprotobuf PROPERTY IMPORTED_LOCATION "${Protobuf_LIBRARY}")
137 + endif()
138 +
139 + if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc)
140 + set(Protobuf_PROTOC_EXECUTABLE protobuf::protoc)
141 + endif()
142 +
143 + # It is technically possible that this may still not
144 + # be set by this point, so we need to check it and
145 + # fail noisily if it isn't because the build won't
146 + # work without it.
147 + if(NOT Protobuf_PROTOC_EXECUTABLE)
148 + message(FATAL_ERROR "Could not determine the location of the protobuf compiler for the detected version of protobuf.")
149 + endif()
150 +
151 + set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
152 + set(PROTOBUF_LIBRARIES protobuf::libprotobuf)
153 endif()
154
155 set(ENABLE_PROTOBUF True)
packaging/docker/gen-cflags.sh
+2 -2
@@ -3,7 +3,7 @@
3 if [ -n "${CFLAGS}" ]; then
4 echo "${CFLAGS}"
5 elif [ -n "${DEBUG_BUILD}" ]; then
6 - echo "-ffunction-sections -fdata-sections -Og -ggdb -pipe"
6 + echo "-Og -ggdb -pipe"
7 else
8 - echo "-ffunction-sections -fdata-sections -O2 -funroll-loops -pipe"
8 + echo "-O2 -funroll-loops -pipe"
9 fi
packaging/makeself/jobs/70-netdata-git.install.sh
+10 -12
@@ -7,38 +7,36 @@
7 cd "${NETDATA_SOURCE_PATH}" || exit 1
8
9 if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then
10 - export CFLAGS="${TUNING_FLAGS} -ffunction-sections -fdata-sections -static -O2 -funroll-loops -DNETDATA_STATIC_BUILD=1 -I/openssl-static/include -I/libnetfilter-acct-static/include/libnetfilter_acct -I/curl-local/include/curl -I/usr/include/libmnl -pipe"
10 + export CFLAGS="${TUNING_FLAGS} -O2 -pipe -funroll-loops -I/openssl-static/include -I/libnetfilter-acct-static/include/libnetfilter_acct -I/curl-local/include/curl -I/usr/include/libmnl"
11 else
12 - export CFLAGS="${TUNING_FLAGS} -static -O1 -pipe -ggdb -Wall -Wextra -Wformat-signedness -DNETDATA_STATIC_BUILD=1 -DNETDATA_INTERNAL_CHECKS=1 -I/openssl-static/include -I/libnetfilter-acct-static/include/libnetfilter_acct -I/curl-local/include/curl -I/usr/include/libmnl"
12 + export CFLAGS="${TUNING_FLAGS} -O1 -pipe -ggdb -Wall -Wextra -Wformat-signedness -DNETDATA_INTERNAL_CHECKS=1 -I/openssl-static/include -I/libnetfilter-acct-static/include/libnetfilter_acct -I/curl-local/include/curl -I/usr/include/libmnl"
13 fi
14
15 -export LDFLAGS="-Wl,--gc-sections -static -L/openssl-static/lib64 -L/libnetfilter-acct-static/lib -lnetfilter_acct -L/usr/lib -lmnl -L/usr/lib -lzstd -L/curl-local/lib"
15 +export LDFLAGS="-Wl,--gc-sections -L/openssl-static/lib64 -L/libnetfilter-acct-static/lib -lnetfilter_acct -L/usr/lib -lmnl -L/usr/lib -lzstd -L/curl-local/lib"
16 +export PKG_CONFIG_PATH="/openssl-static/lib64/pkgconfig:/libnetfilter-acct-static/lib/pkgconfig:/usr/lib/pkgconfig:/curl-local/lib/pkgconfig"
17
18 # We export this to 'yes', installer sets this to .environment.
19 # The updater consumes this one, so that it can tell whether it should update a static install or a non-static one
20 export IS_NETDATA_STATIC_BINARY="yes"
21
21 -# Set eBPF LIBC to "static" to bundle the `-static` variant of the kernel-collector
22 -export EBPF_LIBC="static"
23 -export PKG_CONFIG="pkg-config --static"
24 -export PKG_CONFIG_PATH="/openssl-static/lib64/pkgconfig:/libnetfilter-acct-static/lib/pkgconfig:/usr/lib/pkgconfig:/curl-local/lib/pkgconfig"
25 -
22 NETDATA_BUILD_DIR="$(build_path netdata)"
23 export NETDATA_BUILD_DIR
24
25 +# Needed to make Rust play nice with our static builds
26 +# Once Cargo’s profile-rustflags feature is a bit more widespread, we should switch to using that to specify this.
27 +export RUSTFLAGS="-C target-feature=+crt-static"
28 +
29 case "${BUILDARCH}" in
30 armv6l)
31 - export NETDATA_CMAKE_OPTIONS="-DENABLE_LIBBACKTRACE=On"
31 + export NETDATA_CMAKE_OPTIONS="-DSTATIC_BUILD=On -DENABLE_LIBBACKTRACE=On"
32 export INSTALLER_ARGS="--disable-plugin-systemd-journal --disable-plugin-otel"
33 ;;
34 *)
35 - export NETDATA_CMAKE_OPTIONS="-DENABLE_LIBBACKTRACE=On"
35 + export NETDATA_CMAKE_OPTIONS="-DSTATIC_BUILD=On -DENABLE_LIBBACKTRACE=On"
36 export INSTALLER_ARGS="--enable-plugin-systemd-journal --internal-systemd-journal --enable-plugin-otel"
37 ;;
38 esac
39
40 -export RUSTFLAGS="-C target-feature=+crt-static"
41 -
40 run ./netdata-installer.sh \
41 --install-prefix "${NETDATA_INSTALL_PARENT}" \
42 --dont-wait \
packaging/windows/compile-on-windows.sh
+1 -1
@@ -23,7 +23,7 @@ fi
23 COMMON_CFLAGS="-Wa,-mbig-obj -pipe -D_FILE_OFFSET_BITS=64 -D__USE_MINGW_ANSI_STDIO=1"
24
25 if [ "${CMAKE_BUILD_TYPE}" = "Debug" ]; then
26 - BUILD_CFLAGS="-fstack-protector-all -O0 -ggdb -Wall -Wextra -Wno-char-subscripts -DNETDATA_INTERNAL_CHECKS=1 ${COMMON_CFLAGS} ${CFLAGS:-}"
26 + BUILD_CFLAGS="-O0 -ggdb -Wall -Wextra -Wno-char-subscripts -DNETDATA_INTERNAL_CHECKS=1 ${COMMON_CFLAGS} ${CFLAGS:-}"
27 else
28 BUILD_CFLAGS="-O2 ${COMMON_CFLAGS} ${CFLAGS:-}"
29 fi