Here’s the fifth way. I think it has minimum drawbacks: no profiles, no custom lifecycle, no declarations in child POMs, no ‘skip’ requirement for plugins.
Copied it from https://stackoverflow.com/a/14653088/2053580 — many thanks to end-user!
<build>
<pluginManagement>
<plugins>
<plugin>
<!-- Main declaration and configuration of the plugin -->
<!-- Will be inherited by children -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<!--This must be named-->
<id>checkstyle</id>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<!-- You may also use per-execution configuration block -->
<configuration...>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<!-- This declaration makes sure children get plugin in their lifecycle -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<!-- Configuration won't be propagated to children -->
<inherited>false</inherited>
<executions>
<execution>
<!--This matches and thus overrides execution defined above -->
<id>checkstyle</id>
<!-- Unbind from lifecycle for this POM -->
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>