-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always build a cdecl library #4930
Conversation
TortoiseGit always have been using |
Awesome, thanks for the update. That was my assumption but I appreciate the confirmation. |
I know that nodegit itself does not specify stdcall; however, it is /possible/ (though I doubt it) that the node build system (node-gyp) could be defining stdcall. I've been in meetings for 2 days, but I will get back to you after I have checked. |
We're using |
OK, I've let a few people who are doing FFI and interop on Windows (LibGit2Sharp, etc) and so I think that most people that we know about haven't had any complaints. Holding on to this just so that somebody can have an opportunity to argue with me about the |
The GIT_EXTERN macro needs to provide order-specific attributes; update users of the GIT_DEPRECATED macro to allow for that.
The recommendation from engineers within Microsoft is that libraries should have a calling convention specified in the public API, and that calling convention should be cdecl unless there are strong reasons to use a different calling convention. We previously offered end-users the choice between cdecl and stdcall calling conventions. We did this for presumed wider compatibility: most Windows applications will use cdecl, but C# and PInvoke default to stdcall for WINAPI compatibility. (On Windows, the standard library functions are are stdcall so PInvoke also defaults to stdcall.) However, C# and PInvoke can easily call cdecl APIs by specifying an annotation. Thus, we will explicitly declare ourselves cdecl and remove the option to build as stdcall.
To explicitly break end-users who were specifying STDCALL, explicitly fail the cmake process to ensure that they know that they need to change their bindings. Otherwise, we would quietly ignore their option and the resulting cdecl library would produced undefined behavior.
Since we now always build the library with cdecl calling conventions, our callbacks should be decorated as such so that users will not be able to provide callbacks defined with other calling conventions. The `GIT_CALLBACK` macro will inject the `__cdecl` attribute as appropriate.
1ffb167
to
38e6179
Compare
On Windows, we currently offer end-users the ability to compile the library with cdecl calling conventions (the default) or stdcall calling conventions (an option enabled by
-DSTDCALL=ON
to cmake).The recommendation from engineers within Microsoft is that libraries should have a calling convention specified in the public API, and that calling convention should be cdecl unless there are strong reasons to use a different calling convention.
We offered stdcall for the LibGit2Sharp project, since by default, PInvoke (the .NET FFI) uses stdcall. This is because PInvoke is usually used to call standard library functions, and Win32 is stdcall for historic reasons. But the defaults for all new projects is to use cdecl, and most other modern libraries are using it.
(In either case, we should pick one and declare it in our API. Without having done so, the end user must match our calling conventions in order to even operate. This is onerous, and we should allow interop to programs from any calling convention.)
This PR removes the
STDCALL
option from cmake, and adds the necessarycdecl
attributes toGIT_EXTERN
. In addition, we need to identify the calling conventions for our callbacks, so I've introduced theGIT_CALLBACK
macro to do so and updated our public callbacks to have that attribute.Note that this is a breaking change for anybody who was building with
STDCALL=ON
. However I suspect that LibGit2Sharp is the only consumer who's done that, since it made their bindings somewhat easier. But it's not impossible that there's somebody building with stdcall who will need to update their callbacks to be cdecl (one simply needs to add the attribute).So this is a breaking API change, but I suspect it will not affect too many end users. But @csware and @implausible are probably the most likely to be affected and I'd like their input.
I have a PR for LibGit2Sharp ready to go to move over to cdecl, to ensure that it will work (it does).