@@ -1367,11 +1367,53 @@ SP_EXTRA_FLAGS = -Wno-universal-initializer
1367
1367
SANITIZE_LEAK =
1368
1368
SANITIZE_ADDRESS =
1369
1369
1370
- # For the 'coccicheck' target; setting SPATCH_BATCH_SIZE higher will
1371
- # usually result in less CPU usage at the cost of higher peak memory.
1372
- # Setting it to 0 will feed all files in a single spatch invocation.
1373
- SPATCH_FLAGS = --all-includes
1374
- SPATCH_BATCH_SIZE = 1
1370
+ # For the 'coccicheck' target
1371
+ SPATCH_INCLUDE_FLAGS = --all-includes
1372
+ SPATCH_FLAGS =
1373
+ SPATCH_TEST_FLAGS =
1374
+
1375
+ # If *.o files are present, have "coccicheck" depend on them, with
1376
+ # COMPUTE_HEADER_DEPENDENCIES this will speed up the common-case of
1377
+ # only needing to re-generate coccicheck results for the users of a
1378
+ # given API if it's changed, and not all files in the project. If
1379
+ # COMPUTE_HEADER_DEPENDENCIES=no this will be unset too.
1380
+ SPATCH_USE_O_DEPENDENCIES = YesPlease
1381
+
1382
+ # Set SPATCH_CONCAT_COCCI to concatenate the contrib/cocci/*.cocci
1383
+ # files into a single contrib/cocci/ALL.cocci before running
1384
+ # "coccicheck".
1385
+ #
1386
+ # Pros:
1387
+ #
1388
+ # - Speeds up a one-shot run of "make coccicheck", as we won't have to
1389
+ # parse *.[ch] files N times for the N *.cocci rules
1390
+ #
1391
+ # Cons:
1392
+ #
1393
+ # - Will make incremental development of *.cocci slower, as
1394
+ # e.g. changing strbuf.cocci will re-run all *.cocci.
1395
+ #
1396
+ # - Makes error and performance analysis harder, as rules will be
1397
+ # applied from a monolithic ALL.cocci, rather than
1398
+ # e.g. strbuf.cocci. To work around this either undefine this, or
1399
+ # generate a specific patch, e.g. this will always use strbuf.cocci,
1400
+ # not ALL.cocci:
1401
+ #
1402
+ # make contrib/coccinelle/strbuf.cocci.patch
1403
+ SPATCH_CONCAT_COCCI = YesPlease
1404
+
1405
+ # Rebuild 'coccicheck' if $(SPATCH), its flags etc. change
1406
+ TRACK_SPATCH_DEFINES =
1407
+ TRACK_SPATCH_DEFINES += $(SPATCH )
1408
+ TRACK_SPATCH_DEFINES += $(SPATCH_INCLUDE_FLAGS )
1409
+ TRACK_SPATCH_DEFINES += $(SPATCH_FLAGS )
1410
+ TRACK_SPATCH_DEFINES += $(SPATCH_TEST_FLAGS )
1411
+ GIT-SPATCH-DEFINES : FORCE
1412
+ @FLAGS=' $(TRACK_SPATCH_DEFINES)' ; \
1413
+ if test x" $$ FLAGS" ! = x" ` cat GIT-SPATCH-DEFINES 2> /dev/null` " ; then \
1414
+ echo >&2 " * new spatch flags" ; \
1415
+ echo " $$ FLAGS" > GIT-SPATCH-DEFINES; \
1416
+ fi
1375
1417
1376
1418
include config.mak.uname
1377
1419
-include config.mak.autogen
@@ -3207,35 +3249,113 @@ check: $(GENERATED_H)
3207
3249
exit 1; \
3208
3250
fi
3209
3251
3252
+ COCCI_GEN_ALL = .build/contrib/coccinelle/ALL.cocci
3253
+ COCCI_GLOB = $(wildcard contrib/coccinelle/* .cocci)
3254
+ COCCI_RULES_TRACKED = $(COCCI_GLOB:%=.build/% )
3255
+ COCCI_RULES_TRACKED_NO_PENDING = $(filter-out % .pending.cocci,$(COCCI_RULES_TRACKED ) )
3256
+ COCCI_RULES =
3257
+ COCCI_RULES += $(COCCI_GEN_ALL )
3258
+ COCCI_RULES += $(COCCI_RULES_TRACKED )
3259
+ COCCI_NAMES =
3260
+ COCCI_NAMES += $(COCCI_RULES:.build/contrib/coccinelle/%.cocci=% )
3261
+
3262
+ COCCICHECK_PENDING = $(filter % .pending.cocci,$(COCCI_RULES ) )
3263
+ COCCICHECK = $(filter-out $(COCCICHECK_PENDING ) ,$(COCCI_RULES ) )
3264
+
3265
+ COCCICHECK_PATCHES = $(COCCICHECK:%=%.patch )
3266
+ COCCICHECK_PATCHES_PENDING = $(COCCICHECK_PENDING:%=%.patch )
3267
+
3268
+ COCCICHECK_PATCHES_INTREE = $(COCCICHECK_PATCHES:.build/%=% )
3269
+ COCCICHECK_PATCHES_PENDING_INTREE = $(COCCICHECK_PATCHES_PENDING:.build/%=% )
3270
+
3271
+ # It's expensive to compute the many=many rules below, only eval them
3272
+ # on $(MAKECMDGOALS) that match these $(COCCI_RULES)
3273
+ COCCI_RULES_GLOB =
3274
+ COCCI_RULES_GLOB += cocci%
3275
+ COCCI_RULES_GLOB += .build/contrib/coccinelle/%
3276
+ COCCI_RULES_GLOB += $(COCCICHECK_PATCHES )
3277
+ COCCI_RULES_GLOB += $(COCCICHEC_PATCHES_PENDING )
3278
+ COCCI_RULES_GLOB += $(COCCICHECK_PATCHES_INTREE )
3279
+ COCCI_RULES_GLOB += $(COCCICHECK_PATCHES_PENDING_INTREE )
3280
+ COCCI_GOALS = $(filter $(COCCI_RULES_GLOB ) ,$(MAKECMDGOALS ) )
3281
+
3210
3282
COCCI_TEST_RES = $(wildcard contrib/coccinelle/tests/* .res)
3211
3283
3212
- % .cocci.patch : % .cocci $(COCCI_SOURCES )
3213
- $(QUIET_SPATCH ) \
3214
- if test $( SPATCH_BATCH_SIZE) = 0; then \
3215
- limit=; \
3216
- else \
3217
- limit=' -n $(SPATCH_BATCH_SIZE)' ; \
3218
- fi ; \
3219
- if ! echo $( COCCI_SOURCES) | xargs $$ limit \
3220
- $(SPATCH ) $(SPATCH_FLAGS ) \
3221
- --sp-file $< --patch . \
3222
- > $@ + 2> $@ .log; \
3284
+ $(COCCI_RULES_TRACKED ) : .build/% : %
3285
+ $(call mkdir_p_parent_template)
3286
+ $(QUIET_CP ) cp $< $@
3287
+
3288
+ .build/contrib/coccinelle/FOUND_H_SOURCES : $(FOUND_H_SOURCES )
3289
+ $(call mkdir_p_parent_template)
3290
+ $(QUIET_GEN ) > $@
3291
+
3292
+ $(COCCI_GEN_ALL ) : $(COCCI_RULES_TRACKED_NO_PENDING )
3293
+ $(call mkdir_p_parent_template)
3294
+ $(QUIET_SPATCH_CAT ) cat $^ > $@
3295
+
3296
+ ifeq ($(COMPUTE_HEADER_DEPENDENCIES ) ,no)
3297
+ SPATCH_USE_O_DEPENDENCIES =
3298
+ endif
3299
+ define cocci-rule
3300
+
3301
+ # # Rule for .build/$(1).patch/$(2); Params:
3302
+ # $(1) = e.g. ".build/contrib/coccinelle/free.cocci"
3303
+ # $(2) = e.g. "grep.c"
3304
+ # $(3) = e.g. "grep.o"
3305
+ COCCI_$(1:.build/contrib/coccinelle/%.cocci=% ) += $(1 ) .d/$(2 ) .patch
3306
+ $(1 ) .d/$(2 ) .patch: GIT-SPATCH-DEFINES
3307
+ $(1 ) .d/$(2 ) .patch: $(if $(and $(SPATCH_USE_O_DEPENDENCIES ) ,$(wildcard $(3 ) ) ) ,$(3 ) ,.build/contrib/coccinelle/FOUND_H_SOURCES)
3308
+ $(1 ) .d/$(2 ) .patch: $(1 )
3309
+ $(1 ) .d/$(2 ) .patch: $(1 ) .d/%.patch : %
3310
+ $$(call mkdir_p_parent_template)
3311
+ $$(QUIET_SPATCH ) if ! $$(SPATCH ) $$(SPATCH_FLAGS ) \
3312
+ $$(SPATCH_INCLUDE_FLAGS ) \
3313
+ --sp-file $(1 ) --patch . $$< \
3314
+ >$$@ 2>$$@ .log; \
3223
3315
then \
3224
- cat $@ .log; \
3316
+ echo "ERROR when applying '$(1 ) ' to '$$< '; '$$@ .log' follows:"; \
3317
+ cat $$@ .log; \
3225
3318
exit 1; \
3226
- fi ; \
3227
- mv $@ + $@ ; \
3228
- if test -s $@ ; \
3319
+ fi
3320
+ endef
3321
+
3322
+ define cocci-matrix
3323
+
3324
+ $(foreach s,$(COCCI_SOURCES ) ,$(call cocci-rule,$(c ) ,$(s ) ,$(s:%.c=%.o ) ) )
3325
+ endef
3326
+
3327
+ ifdef COCCI_GOALS
3328
+ $(eval $(foreach c,$(COCCI_RULES),$(call cocci-matrix,$(c))))
3329
+ endif
3330
+
3331
+ define spatch-rule
3332
+
3333
+ .build/contrib/coccinelle/$(1 ) .cocci.patch: $$(COCCI_$(1 ) )
3334
+ $$(QUIET_SPATCH_CAT ) cat $$^ >$$@ && \
3335
+ if test -s $$@ ; \
3229
3336
then \
3230
- echo ' ' SPATCH result: $@ ; \
3337
+ echo ' ' SPATCH result: $$ @ ; \
3231
3338
fi
3339
+ contrib/coccinelle/$(1 ) .cocci.patch: .build/contrib/coccinelle/$(1 ) .cocci.patch
3340
+ $$(QUIET_CP ) cp $$< $$@
3341
+
3342
+ endef
3343
+
3344
+ ifdef COCCI_GOALS
3345
+ $(eval $(foreach n,$(COCCI_NAMES),$(call spatch-rule,$(n))))
3346
+ endif
3232
3347
3233
3348
COCCI_TEST_RES_GEN = $(addprefix .build/,$(COCCI_TEST_RES ) )
3349
+ $(COCCI_TEST_RES_GEN ) : GIT-SPATCH-DEFINES
3234
3350
$(COCCI_TEST_RES_GEN ) : .build/% .res : % .c
3235
3351
$(COCCI_TEST_RES_GEN ) : .build/% .res : % .res
3352
+ ifdef SPATCH_CONCAT_COCCI
3353
+ $(COCCI_TEST_RES_GEN ) : .build/contrib/coccinelle/tests/% .res : $(COCCI_GEN_ALL )
3354
+ else
3236
3355
$(COCCI_TEST_RES_GEN ) : .build/contrib/coccinelle/tests/% .res : contrib/coccinelle/% .cocci
3356
+ endif
3237
3357
$(call mkdir_p_parent_template)
3238
- $(QUIET_SPATCH_T )$(SPATCH ) $(SPATCH_FLAGS ) \
3358
+ $(QUIET_SPATCH_TEST )$(SPATCH) $(SPATCH_TEST_FLAGS ) \
3239
3359
--very-quiet --no-show-diff \
3240
3360
--sp-file $< -o $@ \
3241
3361
$(@:.build/%.res=%.c) && \
@@ -3246,11 +3366,15 @@ $(COCCI_TEST_RES_GEN): .build/contrib/coccinelle/tests/%.res : contrib/coccinell
3246
3366
coccicheck-test : $(COCCI_TEST_RES_GEN )
3247
3367
3248
3368
coccicheck : coccicheck-test
3249
- coccicheck : $(addsuffix .patch,$(filter-out % .pending.cocci,$(wildcard contrib/coccinelle/* .cocci) ) )
3369
+ ifdef SPATCH_CONCAT_COCCI
3370
+ coccicheck : contrib/coccinelle/ALL.cocci.patch
3371
+ else
3372
+ coccicheck : $(COCCICHECK_PATCHES_INTREE )
3373
+ endif
3250
3374
3251
3375
# See contrib/coccinelle/README
3252
3376
coccicheck-pending : coccicheck-test
3253
- coccicheck-pending : $(addsuffix .patch, $( wildcard contrib/coccinelle/ * .pending.cocci) )
3377
+ coccicheck-pending : $(COCCICHECK_PATCHES_PENDING_INTREE )
3254
3378
3255
3379
.PHONY : coccicheck coccicheck-pending
3256
3380
@@ -3517,8 +3641,9 @@ profile-clean:
3517
3641
$(RM ) $(addsuffix * .gcno,$(addprefix $(PROFILE_DIR ) /, $(object_dirs ) ) )
3518
3642
3519
3643
cocciclean :
3644
+ $(RM ) GIT-SPATCH-DEFINES
3520
3645
$(RM ) -r .build/contrib/coccinelle
3521
- $(RM ) contrib/coccinelle/* .cocci.patch*
3646
+ $(RM ) contrib/coccinelle/* .cocci.patch
3522
3647
3523
3648
clean : profile-clean coverage-clean cocciclean
3524
3649
$(RM ) -r .build
0 commit comments