Skip to content
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

Switch default regex engine to PCRE2 #12978

Merged

Conversation

straight-shoota
Copy link
Member

This is the next step for the migration towards PCRE2 (#12790).

With this change PCRE2 becomes the default regex engine.
There's still an automatic fallback when pkg-config can't find libpcre2, so you should still be able to build Crystal programs if libpcre2 is missing on the build system. This will change in a future release, though.

It's always possible to actively choose one or the other with -Duse_pcre and -Duse_pcre2.

The compiler continues to be built with PCRE for now to ensure consistency for regex literals in the language (see #12857).

src/regex/engine.cr Outdated Show resolved Hide resolved
@straight-shoota straight-shoota marked this pull request as draft January 24, 2023 21:20
@straight-shoota
Copy link
Member Author

straight-shoota commented Jan 26, 2023

So it looks like something with PCRE2 JIT support is broken on Windows and leads to invalid memory access (#13013).

All other platforms seem to be working good, though.

I have disabled JIT compilation for win32 (we might want to have some way for configuring that in general). It's not essential and we can still move forward with migrating to PCRE2.

@straight-shoota straight-shoota marked this pull request as ready for review January 26, 2023 22:06
@beta-ziliani
Copy link
Member

After #13056 is merged we can undo the last commits.

Makefile Show resolved Hide resolved
@@ -15,7 +15,7 @@ jobs:
make deps
- name: Cross-compile Crystal
run: |
LLVM_TARGETS=X86 bin/crystal build --cross-compile --target x86_64-pc-windows-msvc src/compiler/crystal.cr -Dwithout_playground -Dwithout_iconv -Dwithout_interpreter
LLVM_TARGETS=X86 bin/crystal build --cross-compile --target x86_64-pc-windows-msvc src/compiler/crystal.cr -Dwithout_playground -Dwithout_iconv -Dwithout_interpreter -Duse_pcre2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This first-generation compiler is still a compiler, so shouldn't it use PCRE1? Or are we intentionally detecting potential PCRE2 errors here? Same for the linker command below

Copy link
Member Author

@straight-shoota straight-shoota Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason to use PCRE2 directly also for the compiler is to drop PCRE completely from the Windows workflow. I guess we could also keep it there, at least for building the compiler. Wouldn't be too hard, but still extra effort.
My rationale is that Windows is still an unsupported preview platform and thus breaking PCRE compatibility isn't that much of a problem.
Of course it's not ideal to have different compiler behaviour on different platforms either, though 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the extra effort required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's just build both libraries, make sure to build the compiler with PCRE and distribute only PCRE2.

Copy link
Contributor

@HertzDevil HertzDevil Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then wouldn't it break all users who try to build the compiler with make -fMakefile.win FLAGS=-Duse_pcre? The only compelling reason not to distribute PCRE1 right now is if the mirror dies, otherwise let's just try to keep things consistent between Windows and other platforms

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, either that or manually install libpcre.

Copy link
Contributor

@HertzDevil HertzDevil Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's rather poor UX. In that case please continue to omit -Duse_pcre in Makefile.win.

Back to this change, I don't think we need -Duse_pcre2 here as it is already the new default (and indeed the second-generation compiler uses PCRE2 because -Duse_pcre isn't present).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? The normal packages as for using crystal to build your (or someone else's) software. Not for building the compiler. We're not shipping a copy of libllvm either - which you need for building the compiler even more than PCRE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason we don't ship LLVM is because the static libraries are too large and we haven't figured out DLL distribution, not that we shouldn't ship it.

Copy link
Member Author

@straight-shoota straight-shoota Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows packaging is another rabbit hole we shouldn't get too deep into with this.

So I was actually wrong, we're still building and shipping PCRE on windows.
I changed it back to build the compiler with PCRE as well.

# and if none is given it tries to check for availability of `libpcre2` with `pkg-config`.
# If `pkg-config` is unavailable, the default is PCRE2. If `pkg-config` is available but
# has no information about a `libpcre2` package, it falls back to PCRE.
{% if flag?(:use_pcre2) || (!flag?(:use_pcre) && (flag?(:win32) || `hash pkg-config 2> /dev/null && (pkg-config --silence-errors --modversion libpcre2-8 || printf %s false) || true` != "false")) %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you run make crystal FLAGS=-Duse_pcre2 then both flags will be present and it is PCRE2 that will be chosen. It seems this is by design, contrary to my suggestion here. Documenting that behavior would be nice even if these flags are temporary

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two steps to remedy this is to err if the two flags are present, and fix the makefile to not add the flag if there's one of these there, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd have to test for both -Duse_pcre2 and -D use_pcre2 with the space inside the Makefile, which sounds rather complex for such a small task, and that's not counting CRYSTAL_OPTS, so perhaps this behavior is fine. It is not like those flags would exist for more than 3 minor releases or something

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants