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

Windows LLVM build (was 'Windows C codegen') #113

Open
snf opened this issue Feb 22, 2019 · 4 comments
Open

Windows LLVM build (was 'Windows C codegen') #113

snf opened this issue Feb 22, 2019 · 4 comments

Comments

@snf
Copy link

snf commented Feb 22, 2019

Hi,
I'm hacking on mrustc to make it build the Windows version of rustc. I got it pretty far to the point I compiled all the libraries and rustc is the only missing part. Patches incoming soon.

The part where I got stuck is the C code being emmitted is not appropiate for VC++. And the problem is I'm not sure how to fix it. I'm writing down what I found.

For function alias in GCC, mrustc emits asm(link_name) attributes. For MSVC, the current approach is creating the functions with the right symbol mangling calling into the original function:

// EXTERN extern "C" ::"libc-0_2_22"::fseek
static int32_t  _ZN12libc$$0_2_225fseek(
		struct e__ZN12libc$$0_2_224FILE *arg0,
		int32_t arg1,
		int32_t arg2
		) {
	return fseek(arg0, arg1, arg2);
}

This works when the function are declared in the headers. Otherwise they are declared implicitally.
The problem is the compiler will default to int whenever the types are implicit. This creates a conflict when the arguments and return types expected have other size. As a result, it ends in a compiler error. A basic example is that pointers are bigger than ints.

My hack has been declaring the external function before calling it from the one with the other name. This results in something like this:

// EXTERN extern "C" ::"libc-0_2_22"::fseek
extern int32_t  fseek(
		struct e__ZN12libc$$0_2_224FILE *arg0,
		int32_t arg1,
		int32_t arg2
		);
static int32_t  _ZN12libc$$0_2_225fseek(
		struct e__ZN12libc$$0_2_224FILE *arg0,
		int32_t arg1,
		int32_t arg2
		) {
	return fseek(arg0, arg1, arg2);
};

The problem with this approach is that we end up re-declaring functions already imported by the headers and sometimes they have conflicting types leading to errors. I'm not aware of a way to detect which functions are declared already to prevent re-declaring them.

The most similar thing to the asm attribute that VC++ supports is #pragma comment(linker, "/alternatename:__a=a") as used here. I haven't tried it yet but it's next in my list.

What do you think? Do you have any other ideas? I'm not super familiar with mrustc source code so I might be missing a better approach.

@snf
Copy link
Author

snf commented Feb 22, 2019

Just noticed that there is a lot of progress in the development branch. The codegen there is using #define which will rename the rest of the functions using this name. I think this might be the solution I'm looking for.

For refence:

                case Compiler::Msvc:
                    //m_of << "#pragma comment(linker, \"/alternatename:_" << Trans_Mangle(p) << "=" << item.m_linkage.name << "\")\n";
                    m_of << "#define " << Trans_Mangle(p) << " " << item.m_linkage.name << "\n";
break;

Have you found any problems using that? I also see that you already tested the pragma alternatename there but I guess it didn't work out.

@thepowersgang
Copy link
Owner

The master branch should "work" (it can compile some basic executables, including many of the build scripts for rustc/cargo).

I've committed/pushed a few fixes today, addressing some minor bugs that were causing crashes and compilation failures, but neither rustc nor cargo are fully building yet (mostly because my windows machine doesn't have LLVM or many of the libraries used by cargo)

@snf
Copy link
Author

snf commented Feb 23, 2019

I got past the libs. The problem is with the more complicated C files generated by rustc. Check my first message in the issue for reference of the bugs you might find later with the codegen. master has the implicit types error I mentioned in my first message (x64 will just fail).

I'm pasting the scripts I used for building LLVM on Monday.

@snf
Copy link
Author

snf commented Feb 25, 2019

For building LLVM:

cmake -v -A x64 -Thost=x64 -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_INCLUDE_EXAMPLES=OFF ^
-DLLVM_ENABLE_ASSERTIONS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_ENABLE_ZLIB=OFF ^
-DWITH_POLLY=OFF -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_USE_CRT_DEBUG=MT ^
-DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_CRT_RELWITHDEBINFO=MT ^
-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-windows-msvc ^
-DCMAKE_INSTALL_PREFIX=F:\projects\mrustc\rustc-1.19.0-src\src\llvm\build\installed ^
..

cmake --build . --target install --config Release

LLVM_CONFIG environment variable then must point to llvm-config in the installed path.

@thepowersgang thepowersgang changed the title Windows C codegen Windows LLVM build (was 'Windows C codegen') Jun 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants