-
Notifications
You must be signed in to change notification settings - Fork 108
various CMake fixes and cleanup #40
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
Conversation
- all the compilers we support have __has_include(), so use that instead of checking it in cmake - nothing in the library uses HAS__ATTRIBUTE__, so remove it
the win32 API uses some architecture-specific defines, but they're not defined by the MSVC compiler - they're defined directly in windows.h based on symbols defined by the MSVC compiler. rather than setting the architecture symbols ourselves, just import windows.h as a whole. this also needed to disable the short-name symbols in cmark-gfm.h, because there are some clashing symbols in win32 headers.
cc @compnerd to check my Windows work |
@@ -0,0 +1,57 @@ | |||
#if __has_include("cmark-gfm-extensions_export.h") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__has_include
is not a standard extension, please add a fallback.
#if __has_include("cmark-gfm-extensions_export.h") | |
#if !defined(__has_include) | |
#define __has_include(include) 0 | |
#endif | |
#if __has_include("cmark-gfm-extensions_export.h") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should i try to find an alternative for the section in mutex.h
where it tries to find and include unistd.h
?
That section already compiles just fine with Clang, GCC, and MSVC, in the situations that i've tried. If we're trying to avoid __has_include
here, i imagine we should provide this fallback for the entire project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that __has_include
was standardized in C++17 - it's valid if this is too new of a target to restrict ourselves to, but it is standard now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is in C++17, however, the project is a C codebase, and does not follow the C++ standards but rather the C standards. I think that providing a fallback is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed some commits that scrub out the uses of __has_include
in the repo, leaving behind one in the prebuilt config.h that's behind a check.
src/include/cmark-gfm_config.h
Outdated
@@ -1,30 +1,24 @@ | |||
#if __has_include("config.h") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern doesn't make sense to me - can you please add extensive comments on each instance for why this is needed. I'm concerned that it can result in recursive includes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea behind this dance is to use the CMake-generated config.h if it's available - that's guaranteed to be applicable to the current compilation environment, as opposed to the guesses that are in the prebuilt headers used by the Swift package. The CMake-generated headers use the same header guard as the prebuilt ones - hence putting this block outside the header guard here. I've pushed a commit that tweaks how these headers are detected (as part of scrubbing out __has_include
), and provides a comment explaining a little of what's going on.
Co-authored-by: Saleem Abdulrasool <compnerd@compnerd.org>
Co-authored-by: Saleem Abdulrasool <compnerd@compnerd.org>
Apologies if I am intruding, but as you have noticed (alas, I started composing this missive before the recent commits), MSVC does not always define the
By comparison
A Godbolt demonstrating the principle at work. I mean to invite no argument by this, mind, it is just for your bemusement. |
@auramarua Right, i noticed the issue with the |
c0c2984
to
6688253
Compare
Sorry about causing the confusion, the setting of the |
adde046
to
492f0b5
Compare
@daniel-grumberg @compnerd mentioned offline that he's good with this PR. You can go ahead and take a look now. |
#include <synchapi.h> | ||
#define _WIN32_WINNT 0x0600 // minimum target of Windows Vista | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <windows.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a blocker, but why are we pulling in the extra stuff from windows.h since synchapi.h is a subset of that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSDN documents that you should use Windows.h and not the specific header. Additionally, there are missing declarations which are required (e.g. _AMD64_
, _ARM64_
or _X86_
which are conditional).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This, basically. When we're just including <synchapi.h>
, one of the headers that that includes needs the architecture-identifying symbols that are only defined in <windows.h>
. That was the problem i ran into when building swift-cmark with CMake instead of SwiftPM on Windows. The best we can do is restrict which headers and symbols get included with things like WIN32_LEAN_AND_MEAN
or various NO{subset}
symbols.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. I didn't look into it that deeply and at the end of day including a bit more stuff than we need to really isn't a big deal since it doesn't affect the build product.
When building swift-cmark/gfm on Windows, there are a number of issues in the CMake configuration and in our statically-generated headers that cause issues:
__declspec(dllexport)
on functions that need to be exported.__builtin_expect
is available, which is not the case for MSVC.<windows.h>
, which we had not properly set up as i was including<synchapi.h>
directly.Because of these and some other issues i saw while working on this, this PR applies a handful of refactors and tweaks to our build configuration:
cmark-gfm_config.h
now checks for the existence of the CMake-generatedconfig.h
, and includes that instead of using the statically-generated version.cmark-gfm_export.h
in build: correct export decoration macros #38 were added tocmark-gfm-extensions_export.h
. However, some changes were made to fix some build issues that happened in Linux with the original change. (__attribute__((__visibility__("protected")))
turned out to cause some problems in Swift's CI.)HAVE___ATTRIBUTE__
) and*_export.h
(CMARK_GFM(_EXTENSIONS)_NO_DEPRECATED
) were removed.HAVE_STDBOOL_H
check was moved from the CMake script into a__has_include
check directly in config.h. This directive is supported in GCC, Clang, and MSVC.<windows.h>
is now included instead of<synchapi.h>
on Windows. However, due to name collisions between cmark's "short" symbol names and some symbols in the Win32 API, short names are disabled universally on Windows.{project}_export.h
headers have been renamed, and import the CMake-generated versions of these headers instead of using the statically-generated version. This is due to an issue in thenmake
specification only building the static libraries, which shouldn't have export attributes on their methods. Since Swift will build as a dynamic library, this isn't a problem forswift build
, but the change was necessary to supportmake
builds.inlines.c
was given an initializer, due to a warning-turned-error in an MSVC build. This has no impact on the behavior, since the variable is guaranteed to be initialized by the time it's accessed, but the static analysis failed to recognize the return statement.With these changes, swift-cmark/gfm builds properly on Windows using
nmake
and by generating projects with CMake.