ChargePoint / xcparse

Command line tool & Swift framework for parsing Xcode 11+ xcresult
MIT License
377 stars 40 forks source link

XCParseCore can not be built for iOS. "Cannot find 'RTLD_DEEPBIND' in scope" #55

Open tonyatoms opened 3 years ago

tonyatoms commented 3 years ago

After adding xcparse as a Swift Package, my app fails to compile with this error: ...SourcePackages/checkouts/swift-package-manager/Sources/SPMUtility/dlopen.swift:63:69: Cannot find 'RTLD_DEEPBIND' in scope

Desktop:

To Reproduce Steps to reproduce the behavior:

  1. Add xcparse to project as Swift Package
  2. Run/Build <- fails

Expected behavior

  1. Add xcparse to project as Swift Package
  2. Run/Build <- suceeds

Additional context Add any other context about the problem here.

RTLD_DEEPBIND is not defined, unlike some of the other constants in dlopen.swift - but this stuff is all a bit over my head.

Also, I don't know if this is a Bug per se, or the result of my installing the package incorrectly or something. I'm very grateful for your work so I hope this report is not burdensome.

abotkin-cpi commented 3 years ago

Yeah not familiar with this error but I'll take a look this weekend. My first guess would be it is due to how xcparse has defined its dependency on SPM versus what your app has defined its dependency. It's possible xcparse set an exact version dependency for SPM rather than a "at or above" SPM version in our Package.swift & perhaps your dependency on SPM requires a higher version. Would you mind mind sharing what your app's dependency declarations are (especially if Swift Package Manager has a version listing)? My email is also in my profile if you'd prefer to email it privately.

tonyatoms commented 3 years ago

Yeah not familiar with this error but I'll take a look this weekend. My first guess would be it is due to how xcparse has defined its dependency on SPM versus what your app has defined its dependency. It's possible xcparse set an exact version dependency for SPM rather than a "at or above" SPM version in our Package.swift & perhaps your dependency on SPM requires a higher version. Would you mind mind sharing what your app's dependency declarations are (especially if Swift Package Manager has a version listing)? My email is also in my profile if you'd prefer to email it privately.

We are not using SPM (yet!) for any other packages, so the app has no SPM dependencies other than what I added by attempting to include xcparse. But I did notice that when I added xcparse, the dependency for SPM that Xcode hooked up was in fact set for exactly 0.5.0. I'm not sure how that happened - but I don't recall doing anything specific about it other than what was listed in the docs for xcparse. (It was a long day yesterday though so I may have botched up something).

I noticed that the current release of SPM is 0.6.0, so I suspect that you may be onto something.

abotkin-cpi commented 3 years ago

@tonyatoms Any chance you haven't set the platforms in your Package.swift to limit to only macOS? I ask as looking in SPM, it appears like that flag should only be used when building for a platform that isn't macOS. That your build is tripping on line 63 seems to imply the preprocessor directive in line 58 went into the else as the build isn't for macOS.

tonyatoms commented 3 years ago

I created a Hello World app just to test this issue and I can re-create it there. It is versioned at: https://github.com/tonyatoms/testingParser

There is no Package.swift in this app except the one introduced through the xcparser swift package.

It could be that I'm misunderstanding the purpose of xcparser. It is clear from the documentation here on github that it is a command line utility. But I'm trying to incorporate it into an iOS app so that I can (eventually) export code coverage from a Jenkins instance. (The simpler avenues of using fastlane tooling such as slather, gcov etc are not an option because I don't have admin access to Jenkins machines.) The blog post at: https://www.chargepoint.com/engineering/xcparse/ shows xcparser being added to an iOS app. I followed those instructions to get to the point where I am at now.

abotkin-cpi commented 3 years ago

Yes, building for iOS would explain the error as xcparse & XCParseCore today only support macOS as the build target.

In the blog post, xcparse isn't being added directly to the iOS app; it's used on a macOS command line prompt to extract screenshots from an xcresult file previously created by Xcode's Test step. That Xcode Test step was testing an iOS app in the Simulator & generated the xcresult with all the screenshots, code coverage information, & logs from the test run. There is a section later on about adding xcparse or XCParseCore to your Swift tools if you want to expand on it (such as Swift Puma did), but those are limited to macOS still.

For your use case, the first thing you'll need to get is the xcresult generated by Xcode when you run Xcode test in the Jenkins job. If that is not getting saved as any build artifact in your Jenkins setup already, you won't have the data that xcparse & XCParseCore extracts to give you the code coverage & screenshots. If you do have the xcresult, on a macOS machine that you control, you can use "brew install ChargePoint/xcparse/xcparse" to install the xcparse CLI and then start extracting code coverage and whatever else.

tonyatoms commented 3 years ago

Ok that all makes sense. Thanks! An xcresult is saved as a result of fastlane/scan on the Jenkins machine, so for the time being I'll just use xcresulttool on that for now.

mattneub commented 3 years ago

I encountered this same error and was helped by this discussion. What I was hoping to do was somehow attach xcparse to my iOS app so that I could run UI tests that take screenshots and then, as the aftermath of the testing, also obtain the screenshots and export them for later handling (because we are required to document our app with a lot of screenshots). I can do this by driving the test with xcbuild and using the homebrew-installed xcparse, but I was hoping to avoid the separate command-line tool as a dependency. Not a big deal, just wanted to let you know what the (very imaginary) use case was supposed to be.