Skip to content

Commit 3b2d368

Browse files
committed
Establish clang-format and some scripts for it
1 parent cf96df5 commit 3b2d368

File tree

5 files changed

+326
-0
lines changed

5 files changed

+326
-0
lines changed

.clang-format

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
---
2+
Language: Cpp
3+
# BasedOnStyle: LLVM
4+
5+
AccessModifierOffset: -4
6+
AlignAfterOpenBracket: AlwaysBreak
7+
AlignConsecutiveAssignments: false
8+
AlignEscapedNewlines: DontAlign
9+
AlignOperands: true
10+
AlignTrailingComments: true
11+
AllowAllParametersOfDeclarationOnNextLine: true
12+
AllowShortBlocksOnASingleLine: false
13+
AllowShortCaseLabelsOnASingleLine: false
14+
AllowShortFunctionsOnASingleLine: None
15+
AllowShortIfStatementsOnASingleLine: false
16+
AllowShortLambdasOnASingleLine: Empty
17+
AllowShortLoopsOnASingleLine: false
18+
AlwaysBreakAfterDefinitionReturnType: None
19+
AlwaysBreakAfterReturnType: None
20+
AlwaysBreakBeforeMultilineStrings: true
21+
AlwaysBreakTemplateDeclarations: MultiLine
22+
BinPackArguments: false
23+
BinPackParameters: false
24+
BraceWrapping:
25+
AfterCaseLabel: true
26+
AfterClass: true
27+
AfterControlStatement: true
28+
AfterEnum: true
29+
AfterFunction: true
30+
AfterNamespace: true
31+
AfterStruct: true
32+
AfterUnion: true
33+
AfterExternBlock: true
34+
BeforeCatch: true
35+
BeforeElse: true
36+
BeforeLambdaBody: true
37+
SplitEmptyFunction: false
38+
SplitEmptyRecord: false
39+
SplitEmptyNamespace: false
40+
BreakBeforeBinaryOperators: None
41+
BreakBeforeBraces: Custom
42+
BreakBeforeTernaryOperators: true
43+
BreakConstructorInitializers: AfterColon
44+
BreakStringLiterals: false
45+
ColumnLimit: 170
46+
CommentPragmas: '^ IWYU pragma:'
47+
CompactNamespaces: true
48+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
49+
ConstructorInitializerIndentWidth: 4
50+
ContinuationIndentWidth: 4
51+
Cpp11BracedListStyle: false
52+
DerivePointerAlignment: false
53+
DisableFormat: false
54+
FixNamespaceComments: true
55+
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
56+
IncludeBlocks: Regroup
57+
IndentCaseLabels: false
58+
IncludeCategories:
59+
- Regex: '^"(stdafx.h|pch.h|precomp.h)"$'
60+
Priority: -1
61+
IndentWidth: 4
62+
IndentWrappedFunctionNames: false
63+
KeepEmptyLinesAtTheStartOfBlocks: true
64+
MacroBlockBegin: '^BEGIN_COM_MAP$|^BEGIN_CONNECTION_POINT_MAP$|^BEGIN_HELPER_NODEMAP$|^BEGIN_MODULE$|^BEGIN_MSG_MAP$|^BEGIN_OBJECT_MAP$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$|^BEGIN_TEST_METHOD_PROPERTIES$'
65+
MacroBlockEnd: '^END_COM_MAP$|^END_CONNECTION_POINT_MAP$|^END_HELPER_NODEMAP$|^END_MODULE$|^END_MSG_MAP$|^END_OBJECT_MAP$|^END_TEST_CLASS$|^END_TEST_METHOD$|^END_TEST_METHOD_PROPERTIES$'
66+
MaxEmptyLinesToKeep: 1
67+
NamespaceIndentation: All
68+
ObjCBlockIndentWidth: 2
69+
ObjCSpaceAfterProperty: false
70+
ObjCSpaceBeforeProtocolList: true
71+
PackConstructorInitializers: NextLineOnly
72+
PenaltyBreakBeforeFirstCallParameter: 19
73+
PenaltyBreakComment: 300
74+
PenaltyBreakFirstLessLess: 120
75+
PenaltyBreakString: 2000
76+
PenaltyExcessCharacter: 2
77+
PenaltyReturnTypeOnItsOwnLine: 1000
78+
PointerAlignment: Left
79+
SortIncludes: false
80+
SpaceAfterCStyleCast: false
81+
SpaceBeforeAssignmentOperators: true
82+
SpaceBeforeParens: ControlStatements
83+
SpaceInEmptyParentheses: false
84+
SpacesBeforeTrailingComments: 1
85+
SpacesInAngles: Never
86+
SpacesInContainerLiterals: true
87+
SpacesInCStyleCastParentheses: false
88+
SpacesInParentheses: false
89+
SpacesInSquareBrackets: false
90+
Standard: Latest
91+
TabWidth: 4
92+
UseTab: Never
93+
94+
AttributeMacros: [
95+
CALLBACK,
96+
]
97+
98+
StatementMacros: [
99+
_Acquires_exclusive_lock_,
100+
_Acquires_lock_,
101+
_Acquires_nonreentrant_lock_,
102+
_Acquires_shared_lock_,
103+
_Analysis_assume_smart_lock_acquired_,
104+
_Analysis_assume_smart_lock_released_,
105+
_Create_lock_level_,
106+
_Detaches_lock_,
107+
_Function_class_,
108+
_Global_cancel_spin_lock_,
109+
_Global_critical_region_,
110+
_Global_interlock_,
111+
_Global_priority_region_,
112+
_Has_lock_kind_,
113+
_Has_lock_level_,
114+
_IRQL_always_function_max_,
115+
_IRQL_always_function_min_,
116+
_IRQL_raises_,
117+
_IRQL_requires_,
118+
_IRQL_requires_max_,
119+
_IRQL_requires_min_,
120+
_IRQL_requires_same_,
121+
_IRQL_restores_,
122+
_IRQL_restores_global_,
123+
_IRQL_saves_,
124+
_IRQL_saves_global_,
125+
_Lock_level_order_,
126+
_Moves_lock_,
127+
_Must_inspect_result_,
128+
_No_competing_thread_,
129+
_Post_same_lock_,
130+
_Post_writable_byte_size_,
131+
_Pre_satisfies_,
132+
_Releases_exclusive_lock_,
133+
_Releases_lock_,
134+
_Releases_nonreentrant_lock_,
135+
_Releases_shared_lock_,
136+
_Replaces_lock_,
137+
_Requires_exclusive_lock_held_,
138+
_Requires_lock_held_,
139+
_Requires_lock_not_held_,
140+
_Requires_no_locks_held_,
141+
_Requires_shared_lock_held_,
142+
_Ret_maybenull_,
143+
_Ret_range_,
144+
_Struct_size_bytes_,
145+
_Success_,
146+
_Swaps_locks_,
147+
_Use_decl_annotations_,
148+
_When_,
149+
150+
DECLARE_ORDINAL_MAP,
151+
DECLARE_PROCNAME_MAP,
152+
DEFINE_ORDINAL_ENTRIES,
153+
DEFINE_ORDINAL_ENTRIES_ALTNAME,
154+
DEFINE_ORDINAL_ENTRIES_APISET,
155+
DEFINE_ORDINAL_MAP,
156+
DEFINE_PROCNAME_ENTRIES,
157+
DEFINE_PROCNAME_ENTRIES_ALTNAME,
158+
DEFINE_PROCNAME_ENTRIES_APISET,
159+
DEFINE_PROCNAME_MAP,
160+
DLOENTRY,
161+
DLOENTRY_APISET,
162+
DLPENTRY,
163+
DLPENTRY_APISET,
164+
165+
RpcEndExcept,
166+
167+
ActivatableClass,
168+
ActivatableClassWithFactory,
169+
ActivatableClassWithFactoryEx,
170+
ActivatableStaticOnlyFactory,
171+
ActivatableStaticOnlyFactoryEx,
172+
CoCreatableClass,
173+
CoCreatableClassWithFactory,
174+
CoCreatableClassWithFactoryEx,
175+
176+
# Additional definitions for the WIL repo
177+
_Translates_NTSTATUS_to_HRESULT_,
178+
_Translates_Win32_to_HRESULT_,
179+
_Translates_last_error_to_HRESULT_,
180+
181+
TEST_CASE,
182+
SECTION,
183+
]
184+
185+
TypenameMacros: [
186+
IFACEMETHOD,
187+
STDMETHOD,
188+
STDAPI_,
189+
]
190+
191+
# Additional definitions for the WIL repo
192+
WhitespaceSensitiveMacros: [
193+
__WI_CLANG_DISABLE_WARNING,
194+
]
195+
196+
# TODO: Only supported by clang-format version 17+
197+
# Macros:
198+
# - WI_NOEXCEPT=noexcept
199+
# - __R_FN_PARAMS_FULL=int x
200+
# - RESULT_NORETURN=[[noreturn]]
201+
---
202+
Language: CSharp
203+
AlignAfterOpenBracket: AlwaysBreak
204+
AllowShortBlocksOnASingleLine: false
205+
AllowShortCaseLabelsOnASingleLine: false
206+
AllowShortFunctionsOnASingleLine: None
207+
AllowShortIfStatementsOnASingleLine: false
208+
AllowShortLoopsOnASingleLine: false
209+
BraceWrapping:
210+
AfterCaseLabel: true
211+
AfterClass: true
212+
AfterControlStatement: true
213+
AfterEnum: true
214+
AfterFunction: true
215+
AfterNamespace: true
216+
AfterStruct: true
217+
BeforeCatch: true
218+
BeforeElse: true
219+
SplitEmptyFunction: true
220+
SplitEmptyRecord: true
221+
SplitEmptyNamespace: true
222+
BreakBeforeBraces: Custom
223+
ColumnLimit: 130
224+
DerivePointerAlignment: false
225+
IndentWidth: 4
226+
PenaltyBreakBeforeFirstCallParameter: 19
227+
PenaltyBreakComment: 300
228+
PenaltyBreakFirstLessLess: 120
229+
PenaltyBreakString: 2000
230+
PenaltyExcessCharacter: 2
231+
PenaltyReturnTypeOnItsOwnLine: 1000
232+
PointerAlignment: Left
233+
TabWidth: 4
234+
UseTab: Never
235+
...
236+

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,40 @@ on:
77
- master
88

99
jobs:
10+
- job: CheckFormatting
11+
12+
pool:
13+
vmImage: 'windows-2022'
14+
15+
steps:
16+
- script: |
17+
if NOT EXIST "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" (
18+
echo ERROR: Could not locate 'vcvars' batch file. This script is intended to be run from a build machine & exit /B 1
19+
)
20+
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
21+
22+
call find_clang_format.cmd
23+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
24+
25+
git clang-format origin/master --binary "%CLANG_FORMAT%" --style file -- cppwinrt/*.h cppwinrt/*.cpp fast_fwd/*.h fast_fwd/*.cpp prebuild/*.h prebuild/*.cpp scratch/*.h scratch/*.cpp strings/*.h strings/*.cpp test/*.h test/*.cpp vsix/*.h vsix/*.cpp
26+
27+
if %ERRORLEVEL% neq 0 (
28+
echo ##vso[task.logissue type=error]ERROR: This branch contains changes that have not been formatted with 'clang-format'
29+
echo NOTE: To resolve this issue, you can run 'clang-format' in the following ways:
30+
echo * Run `build_test_all.cmd` which will run 'clang-format' on _all_ source files. This script is
31+
echo simpler to run, however there's a chance it may touch additional files you never changed due to you having
32+
echo a mis-matched version of 'clang-format'. This may require you to manually revert changes made by
33+
echo 'clang-format' to the locations where you made no code changes.
34+
echo.
35+
echo For more information, please see https://github.com/microsoft/cppwinrt?tab=readme-ov-file#formatting
36+
echo.
37+
echo NOTE: As an additional note, given that different versions of 'clang-format' may have different behaviors, this
38+
echo may be a false positive. If you believe that to be the case ^(e.g. none of the above resulted in modifications
39+
echo to the code you have changed^), please note this in your PR.
40+
exit /b 1
41+
)
42+
displayName: 'Check Formatting of Changes'
43+
1044
test-msvc-cppwinrt-build:
1145
name: '${{ matrix.compiler }}: Build (${{ matrix.arch }}, ${{ matrix.config }})'
1246
strategy:

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,19 @@ a dev command prompt at the root of the repo _after_ following the above build i
3434
* Run `build_prior_projection.cmd` in the dev command prompt as well
3535
* Run `prepare_versionless_diffs.cmd` which removes version stamps on both current and prior projection
3636
* Use a directory-level differencing tool to compare `_build\$(arch)\$(flavor)\winrt` and `_reference\$(arch)\$(flavor)\winrt`
37+
38+
## Formatting
39+
40+
This project has adopted `clang-format` as the tool for formatting our code.
41+
Please note that the `.clang-format` at the root of the repo is a copy from the internal Windows repo with few additions.
42+
In general, please do not modify it.
43+
If you find that a macro is causing bad formatting of code, you can add that macro to one of the corresponding arrays in the `.clang-format` file (e.g. `AttributeMacros`, etc.), format the code, and submit a PR.
44+
45+
> _NOTE: Different versions of `clang-format` may format the same code differently.
46+
In an attempt to maintain consistency between changes, we've standardized on using the version of `clang-format` that ships with the latest version of Visual Studio.
47+
If you have LLVM installed and added to your `PATH`, the version of `clang-format` that gets picked up by default may not be the one we expect.
48+
49+
Before submitting a PR to the cppwinrt repo we ask that you first run `clang-format` on your changes.
50+
There is a CI check in place that will fail the build for your PR if you have not run `clang-format`.
51+
`clang-format` will run automatically as part of `build_test_all.cmd`, so if you use that script this
52+
should happen automatically.

build_test_all.cmd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
@echo off
2+
setlocal
3+
setlocal EnableDelayedExpansion
24

35
set target_platform=%1
46
set target_configuration=%2
@@ -9,13 +11,36 @@ if "%target_platform%"=="" set target_platform=x64
911
if "%target_configuration%"=="" set target_configuration=Release
1012
if "%target_version%"=="" set target_version=1.2.3.4
1113

14+
:: Automatically run clang-format on all .cpp and .h files under the specified directories before building.
15+
call "%~dp0/find_clang_format.cmd"
16+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
17+
18+
set DIRS=cppwinrt fast_fwd prebuild scratch strings test vsix
19+
set EXTS=.cpp .h
20+
for %%d in (%DIRS%) do call :format_files %~dp0%%d
21+
goto :post_format
22+
23+
:format_files
24+
for %%e in (%EXTS%) do (
25+
for /R %1 %%f in (*%%e) do call :run_clang_format "%%f"
26+
)
27+
goto :eof
28+
29+
:run_clang_format
30+
"%CLANG_FORMAT%" -style=file -i %1
31+
goto :eof
32+
33+
:post_format
34+
35+
:: NuGet restore all solutions before building
1236
if not exist ".\.nuget" mkdir ".\.nuget"
1337
if not exist ".\.nuget\nuget.exe" powershell -Command "$ProgressPreference = 'SilentlyContinue' ; Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile .\.nuget\nuget.exe"
1438

1539
call .nuget\nuget.exe restore cppwinrt.sln"
1640
call .nuget\nuget.exe restore natvis\cppwinrtvisualizer.sln
1741
call .nuget\nuget.exe restore test\nuget\NugetTest.sln
1842

43+
:: Build all solutions in order
1944
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:fast_fwd
2045

2146
call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,Deployment=Component;CppWinRTBuildVersion=%target_version% natvis\cppwinrtvisualizer.sln
@@ -37,4 +62,5 @@ call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platfor
3762
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_none
3863
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\old_tests\test_old
3964

65+
:: Run tests after building
4066
call run_tests.cmd %target_platform% %target_configuration%

find_clang_format.cmd

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@echo off
2+
:: NOTE: No 'setlocal' since we're "returning" the definition of "CLANG_FORMAT" to the caller
3+
4+
:: Clang format's behavior has changed over time, meaning that different machines with different versions of LLVM
5+
:: installed may get different formatting behavior. In an attempt to ensure consistency, we use the clang-format.exe
6+
:: that ships with Visual Studio. There may still be issues if two different machines have different versions of Visual
7+
:: Studio installed, however this will hopefully improve things
8+
set CLANG_FORMAT=%VCINSTALLDIR%\Tools\Llvm\bin\clang-format.exe
9+
if not exist "%CLANG_FORMAT%" (
10+
set CLANG_FORMAT=
11+
echo ERROR: clang-format.exe not found at %%VCINSTALLDIR%%\Tools\Llvm\bin\clang-format.exe
12+
echo ERROR: Ensure that this script is being run from a Visual Studio command prompt
13+
exit /B 1
14+
)

0 commit comments

Comments
 (0)