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

Fix Windows codegen (LLVM globals) in non-singlemodule mode #8978

Merged
merged 1 commit into from
Apr 1, 2020

Conversation

oprypin
Copy link
Member

@oprypin oprypin commented Mar 31, 2020

(the suggestions for root causes and fixes all come from @RX14)

Windows compilation so far was always being done in --single-module mode because --cross-compile implies it. But if one adds enough workarounds to try out the compiler on Windows, they would run into these problems, unless --single-module is specified.

  1. __CxxFrameHandler3 is being added only in the main module but can be used in any other module, and the attempt would cause an error:

    Undefined llvm function: __CxxFrameHandler3
    

    Instead, define this function once per module (still on-demand).

    https://gitter.im/crystal-lang/crystal?at=5e7ce5b3bf65703264de4711

  2. void_ptr_type_descriptor is being defined as an LLVM global once per module. But because it's the exact same symbol in all the modules, linking them together leads to this error (repeated per module):

    I-O-5858F-ileD-escriptor43.o : error LNK2005: "void *`RTTI Type Descriptor'" (??_R0PEAX@8) already defined in _main.o.
    

    Instead, define it only in the main module (still on-demand) and then let other modules refer to it as an external constant.

    https://gitter.im/crystal-lang/crystal?at=5e80a76fd71a6e7e8d7efa55

(the suggestions for root causes and fixes all come from @RX14)

Windows compilation so far was always being done in --single-module mode because --cross-compile implies it. But if one adds enough workarounds to try out the compiler *on* Windows, they would run into these problems, unless --single-module is specified.

* Problem 1:

  `__CxxFrameHandler3` is being added only in the main module but can be used in any other module, and the attempt would cause an error:

      Undefined llvm function: __CxxFrameHandler3

  Instead, define this function once per module (still on-demand).

* Problem 2:

  `void_ptr_type_descriptor` is being defined as an LLVM global once per module. But because it's the exact same symbol in all the modules, linking them together leads to this error (repeated per module):

      I-O-5858F-ileD-escriptor43.o : error LNK2005: "void *`RTTI Type Descriptor'" (??_R0PEAX@8) already defined in _main.o.

  Instead, define it only in the main module (still on-demand) and then let other modules refer to it as an external constant.
Copy link
Member

@bcardiff bcardiff left a comment

Choose a reason for hiding this comment

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

The other alternative would be to declare types in the crystal land and access their representation. Allowing the current mecanism to use the type in multiple modules. But I'm fine with the PR as is.

@RX14
Copy link
Contributor

RX14 commented Apr 1, 2020

The other alternative would be to declare types in the crystal land and access their representation

It's actually impossible to represent these types as crystal constants, because we don't support emitting constant math expressions to LLVM (see sub_image_base, Crystal would codegen this as a method call).

@bcardiff bcardiff merged commit ea84350 into crystal-lang:master Apr 1, 2020
@bcardiff bcardiff added this to the 0.34.0 milestone Apr 1, 2020
carlhoerberg pushed a commit to carlhoerberg/crystal that referenced this pull request Apr 29, 2020
…lang#8978)

Windows compilation so far was always being done in --single-module mode because --cross-compile implies it. But if one adds enough workarounds to try out the compiler *on* Windows, they would run into these problems, unless --single-module is specified.

* Problem 1:

  `__CxxFrameHandler3` is being added only in the main module but can be used in any other module, and the attempt would cause an error:

      Undefined llvm function: __CxxFrameHandler3

  Instead, define this function once per module (still on-demand).

* Problem 2:

  `void_ptr_type_descriptor` is being defined as an LLVM global once per module. But because it's the exact same symbol in all the modules, linking them together leads to this error (repeated per module):

      I-O-5858F-ileD-escriptor43.o : error LNK2005: "void *`RTTI Type Descriptor'" (??_R0PEAX@8) already defined in _main.o.

  Instead, define it only in the main module (still on-demand) and then let other modules refer to it as an external constant.
This pull request was closed.
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