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

Build under Windows #13

Open
pultar opened this issue Apr 28, 2024 · 9 comments
Open

Build under Windows #13

pultar opened this issue Apr 28, 2024 · 9 comments

Comments

@pultar
Copy link

pultar commented Apr 28, 2024

Hi, I wanted to build the example projects under Windows 11, Swift 5.10, installation of the toolchain via WinGet following instructions on swift.org.

Swift version 5.10 (swift-5.10-RELEASE)
Target: x86_64-unknown-windows-msvc

When I want to build 3_bidirectional_cxx_interop using

cmake -S . -B build -GNinja
cmake --build build

I get:

-- The CXX compiler identification is Clang 16.0.0 with GNU-like command-line
-- The Swift compiler identification is Apple 5.10
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/clang++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working Swift compiler: C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/swiftc.exe
-- Check for working Swift compiler: C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/swiftc.exe - works
-- Configuring done (4.6s)
-- Generating done (0.0s)
-- Build files have been written to: C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/3_bidirectional_cxx_interop/build

and

[4/6] Linking Swift static library lib\fibonacci\fibonacci.lib
FAILED: lib/fibonacci/fibonacci.lib lib/fibonacci/CMakeFiles/fibonacci.dir/fibonacci.swift.obj lib/fibonacci/SwiftFibonacci.swiftmodule
C:\Windows\system32\cmd.exe /C "cd . && C:\Users\fpultar\AppData\Local\Programs\Swift\Toolchains\5.10.0+Asserts\usr\bin\swiftc.exe -j 32 -num-threads 32 -emit-library -static -o lib\fibonacci\fibonacci.lib -module-name SwiftFibonacci -module-link-name fibonacci -emit-module -emit-module-path lib\fibonacci\SwiftFibonacci.swiftmodule -emit-dependencies  -Onone -g -incremental -libc MDd -cxx-interoperability-mode=default -output-file-map lib\fibonacci\CMakeFiles\fibonacci.dir\Debug\output-file-map.json -I C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/3_bidirectional_cxx_interop/include -I C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/3_bidirectional_cxx_interop/build/lib/fibonacci/include C:\Users\fpultar\source\repos\test-fxp\swift-cmake-examples\3_bidirectional_cxx_interop\lib\fibonacci\fibonacci.swift lib\fibonacci\CMakeFiles\fibonacci.dir\fibonacci.cpp.obj    && cd ."
error: unableToFind(tool: "link")
ninja: build stopped: subcommand failed.

I get similar errors for 2_executable_library.

Forcing building shared libraries (cmake -S . -B build -GNinja -DBUILD_SHARED_LIBS=TRUE) resolves the problem for 2_executable_library but 3_bidirectional_cxx_interop fails with:

[4/6] Linking Swift shared library lib\fibonacci\fibonacci.dll
FAILED: lib/fibonacci/fibonacci.dll lib/fibonacci/CMakeFiles/fibonacci.dir/fibonacci.swift.obj lib/fibonacci/SwiftFibonacci.swiftmodule lib/fibonacci/fibonacci.lib
C:\Windows\system32\cmd.exe /C "cd . && C:\Users\fpultar\AppData\Local\Programs\Swift\Toolchains\5.10.0+Asserts\usr\bin\swiftc.exe -j 32 -num-threads 32 -emit-library -o lib\fibonacci\fibonacci.dll -module-name SwiftFibonacci -module-link-name fibonacci -emit-module -emit-module-path lib\fibonacci\SwiftFibonacci.swiftmodule -emit-dependencies -Dfibonacci_EXPORTS -Onone -g -incremental -libc MDd -cxx-interoperability-mode=default -output-file-map lib\fibonacci\CMakeFiles\fibonacci.dir\Debug\output-file-map.json -I C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/3_bidirectional_cxx_interop/include -I C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/3_bidirectional_cxx_interop/build/lib/fibonacci/include C:\Users\fpultar\source\repos\test-fxp\swift-cmake-examples\3_bidirectional_cxx_interop\lib\fibonacci\fibonacci.swift lib\fibonacci\CMakeFiles\fibonacci.dir\fibonacci.cpp.obj C:\Users\fpultar\AppData\Local\Programs\Swift\Platforms\5.10.0\Windows.platform\Developer\SDKs\Windows.sdk\/usr/lib/swift/windows/x86_64/swiftrt.obj   -Xlinker -implib:lib\fibonacci\fibonacci.lib -L C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/lib/swift/windows   -L C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/lib/swift/windows/x86_64  && cd ."
error: link command failed with exit code 1319 (use -v to see invocation)
fibonacci.cpp.obj : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in swiftrt.obj
fibonacci.cpp.obj : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in swiftrt.obj
C:\Users\fpultar\AppData\Local\Programs\Swift\Platforms\5.10.0\Windows.platform\Developer\SDKs\Windows.sdk\\usr\lib\swift\windows\x86_64\swiftrt.obj : warning LNK4042: object specified more than once; extras ignored
   Creating library lib\fibonacci\fibonacci.lib and object lib\fibonacci\fibonacci.exp
LINK : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
lib\fibonacci\fibonacci.dll : fatal error LNK1319: 2 mismatches detected
clang: error: linker command failed with exit code 1319 (use -v to see invocation)
error: fatalError
ninja: build stopped: subcommand failed.

Do you have any suggestions what could be the issue? I understand that these examples should all work under Windows so I am assuming something might be off with my dev setup.

Best,
Felix

@compnerd
Copy link
Collaborator

error: unableToFind(tool: "link")

This indicates that link.exe was not found in Path. Are you running from within a VS Developer Command Prompt? If not, the MSVC tools required (link.exe) are not in the Path and so the toolchain cannot locate it. Since this is the CMake examples repository, I am assuming that you are building with just CMake. As such, you could work around this by doing -D CMAKE_Swift_FLAGS="-use-ld=lld" to ensure that LLD is always used over the default (link.exe) to link products.

LINK : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library

This indicates that you are building in debug mode. Unfortunately, there is no current support for building with a debug C runtime as the Swift runtime requires the release mode C runtime. You can workaround this by always building in Release or RelWithDebInfo configurations.

@etcwilde - should we perhaps set CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreaded always to allow building the rest of the project in debug mode?

@pultar
Copy link
Author

pultar commented Apr 28, 2024

Thanks for your quick answer!

If I start from C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2022\Visual Studio Tools\Developer Command Prompt for VS 2022 or C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2022\Visual Studio Tools\Developer PowerShell for VS 2022, I get:

 cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
-- The Swift compiler identification is Apple 5.10
-- Check for working Swift compiler: C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/swiftc.exe
-- Check for working Swift compiler: C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/swiftc.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-3.29/Modules/CMakeTestSwiftCompiler.cmake:40 (message):
  The Swift compiler

    "C:/Users/fpultar/AppData/Local/Programs/Swift/Toolchains/5.10.0+Asserts/usr/bin/swiftc.exe"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: 'C:/Users/fpultar/source/repos/test-fxp/swift-cmake-examples/2_executable_library/build/CMakeFiles/CMakeScratch/TryCompile-6my756'

    Run Build Command(s): C:/Users/fpultar/AppData/Local/Microsoft/WinGet/Links/ninja.exe -v cmTC_789a8
    [1/2] C:\Users\fpultar\AppData\Local\Programs\Swift\Toolchains\5.10.0+Asserts\usr\bin\swiftc.exe -j 32 -num-threads 32 -c  -module-name cmTC_789a8 -incremental -output-file-map CMakeFiles\cmTC_789a8.dir\\output-file-map.json  C:\Users\fpultar\source\repos\test-fxp\swift-cmake-examples\2_executable_library\build\CMakeFiles\CMakeScratch\TryCompile-6my756\main.swift
    [2/2] C:\Windows\system32\cmd.exe /C "cd . && C:\Users\fpultar\AppData\Local\Programs\Swift\Toolchains\5.10.0+Asserts\usr\bin\swiftc.exe -j 32 -num-threads 32 -emit-executable -o cmTC_789a8.exe  CMakeFiles\cmTC_789a8.dir\main.swift.obj    && cd ."
    FAILED: cmTC_789a8.exe
    C:\Windows\system32\cmd.exe /C "cd . && C:\Users\fpultar\AppData\Local\Programs\Swift\Toolchains\5.10.0+Asserts\usr\bin\swiftc.exe -j 32 -num-threads 32 -emit-executable -o cmTC_789a8.exe  CMakeFiles\cmTC_789a8.dir\main.swift.obj    && cd ."
       Creating library cmTC_789a8.lib and object cmTC_789a8.exp
    LINK : error LNK2001: unresolved external symbol mainCRTStartup
    C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\lib\x86\msvcrt.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
    C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\lib\x86\msvcprt.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
    cmTC_789a8.exe : fatal error LNK1120: 1 unresolved externals
    clang: error: linker command failed with exit code 1120 (use -v to see invocation)
    ninja: build stopped: subcommand failed.



  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:9 (project)

I have a 64-bit CPU and OS:

Processor	AMD Ryzen 9 7950X 16-Core Processor               4.50 GHz
Installed RAM	192 GB (191 GB usable)
System type	64-bit operating system, x64-based processor

@compnerd
Copy link
Collaborator

You need to use the Native Tools Developer Command Prompt. I believe that the command prompt you are using sets up the environment for 32-bit compilation, not 64-bit. The Windows toolchain defaults to 64-bit compilation, and 32-bit is known to still contain issues :(.

    LINK : error LNK2001: unresolved external symbol mainCRTStartup
    C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\lib\x86\msvcrt.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
    C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\lib\x86\msvcprt.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'

Does seem to match the hypothesis above.

@etcwilde
Copy link
Member

should we perhaps set CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreaded always to allow building the rest of the project in debug mode?

Yeah, I think that makes sense. Is there a drawback to that approach?

@compnerd
Copy link
Collaborator

should we perhaps set CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreaded always to allow building the rest of the project in debug mode?

Yeah, I think that makes sense. Is there a drawback to that approach?

The only drawback that I can think of is future robustness. If we do end up supporting a debug C runtime build of the Swift runtime, it would allow us to support a MultiThreadedDebug variant as well. At the very least, we should be prepared for some day supporting a static variant so that we could do a fully statically linked binary on Windows if desired (even if strongly discouraged by Microsoft).

@pultar
Copy link
Author

pultar commented Apr 29, 2024

It works with the native command prompt using this command:

cmake -S . -B build -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja
cmake --build build

It was necessary to explicitly tell cmake to use clang as MSVC was used otherwise.

The other use case I had in mind was compiling the project on a Mac and a Parallels Windows installation. Following your guidance, I came up with this configure command from the x64_Native_Prompt:

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_SYSTEM_PROCESSOR=AMD64 -DCMAKE_SYSTEM_NAME=Windows
cmake --build build

I suppose that's the logic in InitializeSwift.cmake?

Does it make sense to document these details somewhere in this repo? I am sure it is just my inexperience developing for Windows but that could also be true for other people coming from macOS / Linux.

It's honestly amazing that all these things now also work on Windows. Seems like it can really expand the scope of Swift for cross-platform development!

@compnerd
Copy link
Collaborator

It was necessary to explicitly tell cmake to use clang as MSVC was used otherwise.

Oh, right - if you want to use link, then you need to tell it to use clang and clang++ for the C/C++ compiler.

Does it make sense to document these details somewhere in this repo? I am sure it is just my inexperience developing for Windows but that could also be true for other people coming from macOS / Linux.

I think it makes sense to document these details, but I'm not certain about the location to document it. Perhaps @etcwilde has some thoughts.

It's honestly amazing that all these things now also work on Windows. Seems like it can really expand the scope of Swift for cross-platform development!

I'm happy that you are excited about this - looking forward to see what you build :)

@afabri
Copy link

afabri commented May 3, 2024

This indicates that you are building in debug mode. Unfortunately, there is no current support for building with a debug C runtime as the Swift runtime requires the release mode C runtime. You can workaround this by always building in Release or RelWithDebInfo configurations

Is the "always Release" also true for macOS ? I ask because I have a branch where I fill arrays from the C++ side in order to create a sparse matrix and call a solver from the Accelerate library. It does build but crashes.

@compnerd
Copy link
Collaborator

compnerd commented May 3, 2024

Is the "always Release" also true for macOS ? I ask because I have a branch where I fill arrays from the C++ side in order to create a sparse matrix and call a solver from the Accelerate library. It does build but crashes.

No, the thing is that Microsoft does not have a stable ABI for the C runtime, and you must match that when you build the various components. For performance and redistribution reasons, we build the runtime with the release C runtime, which then requires that we build all client code with the same runtime model.

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

4 participants