diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 83ca8e4182b70ae851c38e37624a2200abae3b24..536a712c65075b1868ffa922cdc1130bbe4e26b4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -414,6 +414,20 @@ jobs: - name: prepare libc6 for actions if: matrix.vector.jobname == 'linux32' run: apt -q update && apt -q -y install libc6-amd64 lib64stdc++6 + - name: install git in container + run: | + if command -v git + then + : # nothing to do + elif command -v apk + then + apk add --update git + elif command -v dnf + then + dnf -yq update && dnf -yq install git + else + apt-get -q update && apt-get -q -y install git + fi - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - run: useradd builder --create-home diff --git a/Makefile b/Makefile index 13f9062a056944621698682e12d871df2487cec2..053eae4f4de92912a28e1513c776e64c87f60da4 100644 --- a/Makefile +++ b/Makefile @@ -1411,8 +1411,7 @@ ARFLAGS = rcs PTHREAD_CFLAGS = # For the 'sparse' target -SPARSE_FLAGS ?= -std=gnu99 -D__STDC_NO_VLA__ -SP_EXTRA_FLAGS = +SPARSE_FLAGS ?= -std=gnu99 # For informing GIT-BUILD-OPTIONS of the SANITIZE=leak,address targets SANITIZE_LEAK = @@ -2858,11 +2857,6 @@ gettext.sp gettext.s gettext.o: GIT-PREFIX gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \ -DGIT_LOCALE_PATH='"$(localedir_relative_SQ)"' -http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SP_EXTRA_FLAGS += \ - -DCURL_DISABLE_TYPECHECK - -pack-revindex.sp: SP_EXTRA_FLAGS += -Wno-memcpy-max-count - ifdef NO_EXPAT http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT endif @@ -2875,7 +2869,6 @@ endif ifdef USE_NED_ALLOCATOR compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \ -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR -compat/nedmalloc/nedmalloc.sp: SP_EXTRA_FLAGS += -Wno-non-pointer-null endif headless-git.o: compat/win32/headless.c GIT-CFLAGS @@ -3300,7 +3293,7 @@ SP_OBJ = $(patsubst %.c,%.sp,$(SP_SRC)) $(SP_OBJ): %.sp: %.c %.o $(GENERATED_H) $(QUIET_SP)cgcc -no-compile $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) \ -Wsparse-error \ - $(SPARSE_FLAGS) $(SP_EXTRA_FLAGS) $< && \ + $(SPARSE_FLAGS) $< && \ >$@ .PHONY: sparse @@ -3330,8 +3323,10 @@ HCC = $(HCO:hco=hcc) $(HCO): %.hco: %.hcc $(GENERATED_H) FORCE $(QUIET_HDR)$(CC) $(ALL_CFLAGS) -o /dev/null -c -xc $< -.PHONY: hdr-check $(HCO) +# TODO: deprecate 'hdr-check' in lieu of 'check-headers' in Git 2.51+ +.PHONY: hdr-check check-headers $(HCO) hdr-check: $(HCO) +check-headers: hdr-check .PHONY: style style: diff --git a/ci/run-static-analysis.sh b/ci/run-static-analysis.sh index ae714e020ae782da7c1ba71f3fc7bc0eecd94f4d..9e9c72681d5715559170f94433080a656a2dfa08 100755 --- a/ci/run-static-analysis.sh +++ b/ci/run-static-analysis.sh @@ -26,7 +26,7 @@ then exit 1 fi -make hdr-check || +make check-headers || exit 1 make check-pot diff --git a/contrib/coccinelle/meson.build b/contrib/coccinelle/meson.build index ea054c924f400f31073a1363e1e854a88cceefa5..dc3f73c2e7b117b79f51128682a5aa21739e6311 100644 --- a/contrib/coccinelle/meson.build +++ b/contrib/coccinelle/meson.build @@ -8,21 +8,6 @@ if not spatch.found() subdir_done() endif -third_party_sources = [ - ':!contrib', - ':!compat/inet_ntop.c', - ':!compat/inet_pton.c', - ':!compat/nedmalloc', - ':!compat/obstack.*', - ':!compat/poll', - ':!compat/regex', - ':!sha1collisiondetection', - ':!sha1dc', - ':!t/unit-tests/clar', - ':!t/unit-tests/clar', - ':!t/t[0-9][0-9][0-9][0-9]*', -] - rules = [ 'array.cocci', 'commit.cocci', @@ -55,18 +40,18 @@ concatenated_rules = custom_target( capture: true, ) -sources = [ ] -foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_sources, check: true).stdout().split() - sources += source +coccinelle_sources = [] +foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_excludes, check: true).stdout().split() + coccinelle_sources += source endforeach -headers = [ ] -foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_sources, check: true).stdout().split() - headers += meson.project_source_root() / header +coccinelle_headers = [] +foreach header : headers_to_check + coccinelle_headers += meson.project_source_root() / header endforeach patches = [ ] -foreach source : sources +foreach source : coccinelle_sources patches += custom_target( command: [ spatch, @@ -78,7 +63,7 @@ foreach source : sources input: meson.project_source_root() / source, output: source.underscorify() + '.patch', capture: true, - depend_files: headers, + depend_files: coccinelle_headers, ) endforeach diff --git a/meson.build b/meson.build index c47cb79af0815a9bdd5acb0ae036c41dff2647fa..afb10052bfc7cf98a9c59b898f72ea019d56e8d2 100644 --- a/meson.build +++ b/meson.build @@ -235,6 +235,7 @@ git = find_program('git', dirs: program_path, native: true, required: false) sed = find_program('sed', dirs: program_path, native: true) shell = find_program('sh', dirs: program_path, native: true) tar = find_program('tar', dirs: program_path, native: true) +cgcc = find_program('cgcc', dirs: program_path, required: false, native: true) target_shell = find_program('sh', dirs: program_path, native: false) @@ -531,7 +532,8 @@ libgit_sources = [ 'xdiff/xutils.c', ] -libgit_sources += custom_target( +libgit_targets = [] +libgit_targets += custom_target( input: 'command-list.txt', output: 'command-list.h', command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'], @@ -666,11 +668,34 @@ builtin_sources = [ 'builtin/write-tree.c', ] +third_party_excludes = [ + ':!contrib', + ':!compat/inet_ntop.c', + ':!compat/inet_pton.c', + ':!compat/nedmalloc', + ':!compat/obstack.*', + ':!compat/poll', + ':!compat/regex', + ':!sha1collisiondetection', + ':!sha1dc', + ':!t/unit-tests/clar', + ':!t/t[0-9][0-9][0-9][0-9]*', + ':!xdiff', +] + +headers_to_check = [] +if git.found() and fs.exists(meson.project_source_root() / '.git') + foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: true).stdout().split() + headers_to_check += header + endforeach +endif + if not get_option('breaking_changes') builtin_sources += 'builtin/pack-redundant.c' endif -builtin_sources += custom_target( +builtin_targets = [] +builtin_targets += custom_target( output: 'config-list.h', command: [ shell, @@ -681,7 +706,7 @@ builtin_sources += custom_target( env: script_environment, ) -builtin_sources += custom_target( +builtin_targets += custom_target( input: 'Documentation/githooks.adoc', output: 'hook-list.h', command: [ @@ -1091,6 +1116,8 @@ else endif libgit_dependencies += networking_dependencies +message('ndepend', '@0@'.format(networking_dependencies)) + foreach symbol : ['inet_ntop', 'inet_pton', 'strerror'] if not compiler.has_function(symbol, dependencies: networking_dependencies) libgit_c_args += '-DNO_' + symbol.to_upper() @@ -1624,11 +1651,11 @@ version_def_h = custom_target( depends: [git_version_file], env: version_gen_environment, ) -libgit_sources += version_def_h +libgit_targets += version_def_h libgit = declare_dependency( link_with: static_library('git', - sources: libgit_sources, + sources: libgit_sources + libgit_targets, c_args: libgit_c_args + [ '-DGIT_VERSION_H="' + version_def_h.full_path() + '"', ], @@ -1690,7 +1717,7 @@ bin_wrappers = [ ] test_dependencies = [ ] git_builtin = executable('git', - sources: builtin_sources + 'git.c', + sources: builtin_sources + builtin_targets + 'git.c', dependencies: [libgit_commonmain], install: true, install_dir: get_option('libexecdir') / 'git-core', @@ -2012,6 +2039,103 @@ endif subdir('contrib') +exclude_from_check_headers = [ + 'compat/', + 'unicode-width.h', +] + +if sha1_backend != 'openssl' + exclude_from_check_headers += 'sha1/openssl.h' +endif +if sha256_backend != 'openssl' + exclude_from_check_headers += 'sha256/openssl.h' +endif +if sha256_backend != 'nettle' + exclude_from_check_headers += 'sha256/nettle.h' +endif +if sha256_backend != 'gcrypt' + exclude_from_check_headers += 'sha256/gcrypt.h' +endif + +if headers_to_check.length() != 0 and compiler.get_argument_syntax() == 'gcc' + hco_targets = [] + foreach h : headers_to_check + skip_header = false + foreach exclude : exclude_from_check_headers + if h.startswith(exclude) + skip_header = true + break + endif + endforeach + + if skip_header + continue + endif + + hcc = custom_target( + input: h, + output: h.underscorify() + 'cc', + command: [ + shell, + '-c', + 'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo \'#include "' + h + '"\' >> @OUTPUT@' + ] + ) + + hco = custom_target( + input: hcc, + output: fs.replace_suffix(h.underscorify(), '.hco'), + command: [ + compiler.cmd_array(), + libgit_c_args, + '-I', meson.project_source_root(), + '-I', meson.project_source_root() / 't/unit-tests', + '-o', '/dev/null', + '-c', '-xc', + '@INPUT@' + ] + ) + hco_targets += hco + endforeach + + # TODO: deprecate 'hdr-check' in lieu of 'check-headers' in Git 2.51+ + hdr_check = alias_target('hdr-check', hco_targets) + alias_target('check-headers', hdr_check) +endif + +if cgcc.found() and meson.version().version_compare('>=1.5.0') + sparse_flags = get_option('sparse_flags') + sparse_targets = [] + sparse_dependencies = [] + + foreach dep : libgit_dependencies + message('dep', dep.name()) + message(dep.get_variable(default_value: '', pkgconfig: 'includeDir')) + endforeach + + foreach source : builtin_sources + libgit_sources + st = custom_target( + input: source, + output: fs.replace_suffix(source.underscorify(), '.sp'), + depends: [ git_builtin ], + command: [ + 'cgcc', + '-no-compile', + '-I', meson.project_source_root(), + '-I', meson.project_source_root() / 't/unit-tests', + '-I', meson.project_build_root(), + libgit_c_args, + '-Wsparse-error', + sparse_flags, + '@INPUT@' + ] + ) + sparse_targets += st + endforeach + + alias_target('sparse', sparse_targets) +endif + foreach key, value : { 'DIFF': diff.full_path(), 'GIT_SOURCE_DIR': meson.project_source_root(), diff --git a/meson_options.txt b/meson_options.txt index 78d172a74019a45f7ca4b535bc06b7fa0e112ebf..9ad88230283f4363f0efd16525ef6a32a8f57903 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -100,9 +100,13 @@ option('default_help_format', type: 'combo', choices: ['man', 'html'], value: 'm option('docs_backend', type: 'combo', choices: ['asciidoc', 'asciidoctor', 'auto'], value: 'auto', description: 'Which backend to use to generate documentation.') -# Testing. +# Static checks option('coccinelle', type: 'feature', value: 'auto', description: 'Provide a coccicheck target that generates a Coccinelle patch.') +option('sparse_flags', type: 'array', value: ['-std=gnu99'], + description: 'Which flags to pass along to the sparse check.') + +# Testing. option('tests', type: 'boolean', value: true, description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.') option('test_output_directory', type: 'string',