-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[SR-1503] Can't test module under linux that has main.swift in it #5372
Comments
Comment by Bhargav Gurlanka (JIRA) I'm able to reproduce this issue. I think the |
This is a known issue, executables are not yet testable. |
This isn't something we can currently solve, at least in the way desired for here, where the Tests module is actually capable of importing the code in the executable module. There are a couple reasons why this is difficult: 1. On Linux, where we need the tests to be a main executable (because of the XCTest implementation), then it isn't going to be possible to link together at all, because of the two main implementations. This is the immediate blocker. 2. Even if we didn't have a main executable, it isn't always possible to link for code which is compiled as the main executable. This is possible with Mach-O images, but I'm not sure if ELF does and I'm not 100% sure that Swift doesn't make assumptions about optimization of modules with main functions. 3. We could try and pull some switch where we built the executable but without its main.swift, but that would require duplicate compilation and break the Swift whole module compilation model (or at least, make it surprising). The situation here is exactly like it is with C/C++ – if you want to be able to dynamically share/load a body of code it needs to be put into a library, not an executable. I think what we should actually do for this specific code is not put the swift module for executables in a place it can be imported, but we can't otherwise support this without a radically different testing model which depends on the compilers ability to understand the test code (and compile it onto the side, or something). |
I thought of one possible way we could do this... We could allow the Package to declare its "entry points", and make executables just a kind of entry point, and let SwiftPM synthesize the code for the main executable. This would allow you to avoid ever writing the `main.swift` if it was as simple as a single function call. The upside of this approach is it also encourages people to write command line tools as testable libraries, which I think is a good thing. The downsides is it doesn't work with any other top-level code, which is very useful for small / script-style command line executables, so we would end up with two ways of doing things. I'm not sure this is a good idea, but it is a feature I have seen before (Python's distutils can do this with its entry_points (http://python-packaging-user-guide.readthedocs.io/en/latest/distributing/#entry-points)). |
I'm a bit concerned that we have left this open for three years without even proposing a documentation or error change to work around it. SwiftPM does actually know if a module has a `main.swift` in it, and we could surely arrange to get a somewhat helpful error message emitted that says "It looks like you're trying to test an executable: this isn't supported, consider moving the code you want to test into a library module instead." I've spoken to people who tried out Swift and bounced off because they hit this, which results in an ugly linker error. While I'm here, I should note that the |
@swift-ci create |
This is no longer reproducible with Swift 5.9. |
Additional Detail from JIRA
md5: b9c178bab17c28c88cc66850ac41c98e
is duplicated by:
Issue Description:
If I have a directory that has a source file and a main.swift in it (e.g. Sources/Foo/main.swift and Sources/Foo/Foo.swift) I can't write run a test for Foo.swift. I get an error that looks like this:
The text was updated successfully, but these errors were encountered: