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

Add minimal load-time DLL support on Windows, support dllimport storage class #11573

Merged

Conversation

HertzDevil
Copy link
Contributor

@HertzDevil HertzDevil commented Dec 12, 2021

This patch is required for minimal support of load-time dynamic linking on Windows. For this to work,

  • Prepare a directory, distinct from the current Crystal installation's CRYSTAL_LIBRARY_PATH, which we will use to place the .lib and .exp files. Set CRYSTAL_LIBRARY_PATH to point to it;
  • Build the minimal dynamic libraries needed by the runtime. Run the following in Powershell: (this is based on the CI job)
    git clone --config core.autocrlf=false -b v8.2.0 https://github.com/ivmai/bdwgc bdwgc
    git clone --config core.autocrlf=false -b v7.6.10 https://github.com/ivmai/libatomic_ops bdwgc\libatomic_ops
    cd bdwgc
    cmake . -DBUILD_SHARED_LIBS=ON -Denable_large_config=ON -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF
    cmake --build . --config Release
    cd ..
    
    Invoke-WebRequest https://cs.stanford.edu/pub/exim/pcre/pcre-8.43.zip -OutFile pcre.zip
    7z x pcre.zip
    Move-Item pcre-* pcre
    cd pcre
    cmake . -DBUILD_SHARED_LIBS=ON -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF -DPCRE_SUPPORT_UNICODE_PROPERTIES=ON -DPCRE_SUPPORT_JIT=ON -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF
    cmake --build . --config Release
    cd ..
  • Copy ./bdwgc/Release/gc.lib and ./pcre/Release/pcre.lib to the CRYSTAL_LIBRARY_PATH we just set. Same for the associated .exp files;
  • Build a test program:
    > echo puts ARGV[0].match(/../) > pcretest.cr
    > crystal build pcretest.cr -Dpreview_dll -Dwithout_iconv
  • Place gc.dll and pcre.dll in the same directory as the pcretest.exe executable;
  • Run it!
    > pcretest 123
    Regex::MatchData("12")

Without this patch, the compilation step would fail with:

_main.obj : error LNK2019: unresolved external symbol pcre_malloc referenced in function __crystal_main
_main.obj : error LNK2019: unresolved external symbol pcre_free referenced in function __crystal_main
G-C-.obj : error LNK2019: unresolved external symbol GC_stackbottom referenced in function .2A.GC.3A..3A.current_thread_stack_bottom.3A.Tuple.28.Pointer.28.Void.29..2C..20.Pointer.28.Void.29..29.

This PR thus adds the dllimport storage class to any external lib variables, through LLVM.

The -Dpreview_dll flag is also added because currently the compiler defaults to static builds on Windows, even without the --static build flag, and everything would immediately break if the current command line suddenly starts using dynamic linking. With a minimal working example we can later sort out the details for dynamic linking on Windows.

@HertzDevil HertzDevil added kind:feature platform:windows Windows support based on the MSVC toolchain topic:compiler:codegen labels Dec 12, 2021
@HertzDevil HertzDevil changed the title Add dllimport storage class to external lib variables on Windows Add minimal load-time DLL support on Windows, support dllimport storage class Dec 12, 2021
@oprypin oprypin self-requested a review December 12, 2021 08:51
@straight-shoota straight-shoota added this to the 1.3.0 milestone Dec 12, 2021
@straight-shoota straight-shoota merged commit eee1a02 into crystal-lang:master Dec 13, 2021
@HertzDevil HertzDevil deleted the feature/windows-dllimport branch December 14, 2021 04:09
@HertzDevil
Copy link
Contributor Author

The instructions to build PCRE2, which is necessary since Crystal 1.8.0, are:

git clone --config core.autocrlf=false -b pcre2-10.42 https://github.com/PCRE2Project/pcre2.git pcre2
cd pcre2
cmake . -DBUILD_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -DPCRE2_BUILD_PCRE2GREP=OFF -DPCRE2_BUILD_TESTS=OFF -DPCRE2_SUPPORT_UNICODE=ON -DPCRE2_SUPPORT_JIT=ON -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF
cmake --build . --config Release
cd ..
copy pcre2\Release\pcre2-8.lib .
copy pcre2\Release\pcre2-8.dll .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:feature platform:windows Windows support based on the MSVC toolchain topic:compiler:codegen
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants