Skip to content

Fixed for Cygwin #733

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/Basic/TerminalController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ public final class TerminalController {

// Try determining using ioctl.
var ws = winsize()
#if !CYGWIN
Copy link
Contributor

Choose a reason for hiding this comment

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

Does Swift itself not define an os condition for Cygwin?

Copy link
Author

Choose a reason for hiding this comment

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

I couldn't use it.
os(Cygwin) PR (swiftlang/swift#2351) was not accepted for Swift compiler.
There were some opinions that Cygwin is only an environment and not OS, and os(Windows) is true for all Windows variants.
We can not distinguish the Cygwin from other Windows variant, MSVC, MinGW.
os(Windows) and CYGWIN macro will be evaluated to true for Cygwin environment.
The CYGWIN macro is also used in Swift standard library.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it... I hope eventually there is some builtin way to identify this.

if ioctl(1, UInt(TIOCGWINSZ), &ws) == 0 {
return Int(ws.ws_col)
}
#endif
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions Sources/Build/Command.link(ClangModule).swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ extension Command {
// Linux doesn't search executable directory for shared libs so embed runtime search path.
#if os(Linux)
args += ["-Xlinker", "-rpath=$ORIGIN"]
#elseif CYGWIN
args += ["-Xlinker", "--allow-multiple-definition"]
#endif
args += linkFlags
args += objects.map{ $0.asString }
Expand Down
9 changes: 9 additions & 0 deletions Sources/Build/Command.link(SwiftModule).swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,21 @@ extension Command {
args += ["-L\(prefix.asString)"]
args += ["-o", outpath.asString]

#if CYGWIN
args += ["-Xlinker", "--allow-multiple-definition"]
#endif

case .Library(.Static):
let inputs = buildables.map{ $0.targetName } + objects.map{ $0.asString }
let outputs = [outpath.asString]
return Command(name: product.targetName, tool: ArchiveTool(inputs: inputs, outputs: outputs))
}

#if CYGWIN
args += ["-D", "CYGWIN"]
args += ["-I", "/usr/include"]
#endif

switch product.type {
case .Library(.Static):
args.append(outpath.asString)
Expand Down
2 changes: 1 addition & 1 deletion Sources/POSIX/popen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public func popen(_ arguments: [String], redirectStandardError: Bool = false, en
}

// Create the file actions to use for spawning.
#if os(macOS)
#if os(macOS) || CYGWIN
var fileActions: posix_spawn_file_actions_t? = nil
#else
var fileActions = posix_spawn_file_actions_t()
Expand Down
11 changes: 10 additions & 1 deletion Sources/POSIX/system.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public func system(_ arguments: [String], environment: [String:String]? = nil) t
public func system() {}


#if os(macOS)
#if os(macOS) || CYGWIN
typealias swiftpm_posix_spawn_file_actions_t = posix_spawn_file_actions_t?
#else
typealias swiftpm_posix_spawn_file_actions_t = posix_spawn_file_actions_t
Expand Down Expand Up @@ -90,7 +90,16 @@ private func WEXITSTATUS(_ status: CInt) -> CInt {
func waitpid(_ pid: pid_t) throws -> Int32 {
while true {
var exitStatus: Int32 = 0
#if CYGWIN
var rv : Int32 = -1
withUnsafeMutablePointer(to: &exitStatus) {
exitStatusPtr in
let exitStatusPtrWrapper = __wait_status_ptr_t(__int_ptr: exitStatusPtr)
rv = waitpid(pid, exitStatusPtrWrapper, 0)
}
#else
let rv = waitpid(pid, &exitStatus, 0)
#endif

if rv != -1 {
if WIFEXITED(exitStatus) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageDescription/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if os(Linux)
#if os(Linux) || CYGWIN
import Glibc
#else
import Darwin.C
Expand Down
4 changes: 4 additions & 0 deletions Sources/PackageLoading/ManifestLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ public final class ManifestLoader: ManifestLoaderProtocol {
var cmd = [resources.swiftCompilerPath.asString]
cmd += ["--driver-mode=swift"]
cmd += verbosity.ccArgs
#if CYGWIN
cmd += ["-D", "CYGWIN"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this used in the current patch?

Copy link
Author

Choose a reason for hiding this comment

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

This is necessary to distinguish Cygwin from other Windows variants.

Copy link
Contributor

Choose a reason for hiding this comment

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

This code is loading the manifest though, and we don't want users to conditionalize their manifests in this way. Since it isn't currently required, I recommend we avoid it here.

cmd += ["-I", "/usr/include"]
#endif
cmd += ["-I", resources.libraryPath.asString]

// When running from Xcode, load PackageDescription.framework
Expand Down
2 changes: 2 additions & 0 deletions Sources/PackageModel/Product.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public class Product {
// configuration.
#if os(macOS)
public static let dynamicLibraryExtension = "dylib"
#elseif CYGWIN
public static let dynamicLibraryExtension = "dll"
#else
public static let dynamicLibraryExtension = "so"
#endif
Expand Down
2 changes: 1 addition & 1 deletion Sources/libc/dirent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
This file defines a common type alias for the result of opendir().
*/

#if os(Linux)
#if os(Linux) || CYGWIN
public typealias DirHandle = OpaquePointer
#else
public typealias DirHandle = UnsafeMutablePointer<DIR>
Expand Down
19 changes: 17 additions & 2 deletions Utilities/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ if platform.system() == 'Darwin':

if platform.system() == 'Linux':
g_shared_lib_ext = ".so"
elif platform.system().startswith('CYGWIN'):
g_shared_lib_ext = ".dll"
else:
g_shared_lib_ext = ".dylib"

Expand Down Expand Up @@ -321,10 +323,10 @@ def parse_manifest():
# We have a *very* strict format for our manifest to make parsing more
# robust. We use this to determine the target and product definitions.
target_pattern = re.compile(
r'Target\(.*?name: "(.*?)",\n *dependencies: (\[.*?\])\)',
r'Target\(.*?name: "(.*?)",\r?\n? *dependencies: (\[.*?\])\)',
re.DOTALL | re.MULTILINE)
product_pattern = re.compile(
r'Library\([\n ]*name: \"(.*?)\",[\n ]*type: (.*?),[\n ]*targets: (\[.*?\])[\n ]*\)',
r'Library\([\r\n ]*name: \"(.*?)\",[\r\n ]*type: (.*?),[\r\n ]*targets: (\[.*?\])[\r\n ]*\)',
re.DOTALL | re.MULTILINE)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should need this, there should be a way to open the manifest file such that Python will automatically do the line ending conversion on reading the data.


# Load the manifest as a string (we always assume UTF-8 encoding).
Expand Down Expand Up @@ -560,6 +562,8 @@ def create_bootstrap_files(sandbox_path, args):
link_command.extend(["-L", args.foundation_path])
if args.libdispatch_build_dir:
link_command.extend(["-L", os.path.join(args.libdispatch_build_dir, "src", ".libs")])
if not target.is_library and platform.system().startswith("CYGWIN"):
link_command.extend(["-Xlinker", "--allow-multiple-definition"])

# Write out the link command.
if target.is_library:
Expand Down Expand Up @@ -644,12 +648,21 @@ def process_runtime_libraries(build_path, args, bootstrap=False):
# We include an RPATH entry so that the Swift libraries can be found
# relative to where it will be installed (in 'lib/swift/pm/...').
runtime_lib_path = os.path.join(lib_path, "libPackageDescription.so")

# Change shared object extension for Cygwin
if platform.system().startswith("CYGWIN"):
runtime_lib_path = os.path.join(lib_path, "libPackageDescription.dll")

cmd = [args.swiftc_path, "-Xlinker", "-shared", "-o", runtime_lib_path,
"-Xlinker", "--whole-archive",
"-Xlinker", input_lib_path,
"-Xlinker", "--no-whole-archive", "-lswiftGlibc",
"-Xlinker", "-rpath=$ORIGIN/../linux"]

# Add link flags for Cygwin
if platform.system().startswith("CYGWIN"):
cmd.extend(["-Xlinker", "--allow-multiple-definition"])

# We need to pass one swift file here to bypass the "no input files"
# error.
tf = tempfile.NamedTemporaryFile(suffix=".swift")
Expand Down Expand Up @@ -895,6 +908,8 @@ def main():
# libraries.
if platform.system() == 'Linux':
embed_rpath = "$ORIGIN/../lib/swift/linux"
elif platform.system().startswith('CYGWIN'):
embed_rpath = "$ORIGIN/../lib/swift/cygwin"
else:
embed_rpath = "@executable_path/../lib/swift/macosx"
build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", embed_rpath])
Expand Down