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 fails on Mono as fs{lex,yacc}.exe not executable #4

Closed
rneatherway opened this issue May 28, 2014 · 5 comments
Closed

Build fails on Mono as fs{lex,yacc}.exe not executable #4

rneatherway opened this issue May 28, 2014 · 5 comments

Comments

@rneatherway
Copy link

Mono's Process.Start will not run a .exe file unless it is marked exectuable. It's not clear if this behaviour is deliberate or not. See this bug report: https://bugzilla.xamarin.com/show_bug.cgi?id=17537

The lkg bootstrap fs{lex,yacc}.exe do not have executable permission set and so the build fails (error at the bottom).

However, this is not just a problem for the build, if the permissions are not set in the NuGet package either, then this package cannot be used on Mono without a manual step (such as find packages -name "*.exe" | xargs chmod +x) after the package is downloaded. How can we address this? Is it possible to run a postinstall script on the package for example, or (less clean) to adjust the FsLex and FsYacc MSBuild tasks so that they set the executable bit on Mono before running?

/auto/users/robnea/dev/tmp/FsLexYacc/FsLexYacc.sln (Rebuild) ->
(Rebuild target) ->
/auto/users/robnea/dev/tmp/FsLexYacc/src/FsLex/FsLex.fsproj (Rebuild) ->
/auto/users/robnea/dev/tmp/FsLexYacc/lkg/FSharp.PowerPack-1.9.7.7/bin/FSharp.PowerPack.targets (CallFsLex target) ->

    /auto/users/robnea/dev/tmp/FsLexYacc/lkg/FSharp.PowerPack-1.9.7.7/bin/FSharp.PowerPack.targets: error : Error executing tool '../../lkg/FSharp.PowerPack-1.9.7.7/bin/FsLex.exe': ApplicationName='../../lkg/FSharp.PowerPack-1.9.7.7/bin/FsLex.exe', CommandLine='-o fslexlex.fs --unicode --lexlib Internal.Utilities.Text.Lexing  fslexlex.fsl ', CurrentDirectory='/auto/users/robnea/dev/tmp/FsLexYacc/src/FsLex', Native error= Cannot find the specified file

/auto/users/robnea/dev/tmp/FsLexYacc/FsLexYacc.sln (Rebuild) ->
(Rebuild target) ->
/auto/users/robnea/dev/tmp/FsLexYacc/src/FsYacc/FsYacc.fsproj (Rebuild) ->
/auto/users/robnea/dev/tmp/FsLexYacc/lkg/FSharp.PowerPack-1.9.7.7/bin/FSharp.PowerPack.targets (CallFsLex target) ->

    /auto/users/robnea/dev/tmp/FsLexYacc/lkg/FSharp.PowerPack-1.9.7.7/bin/FSharp.PowerPack.targets: error : Error executing tool '../../lkg/FSharp.PowerPack-1.9.7.7/bin/FsLex.exe': ApplicationName='../../lkg/FSharp.PowerPack-1.9.7.7/bin/FsLex.exe', CommandLine='-o fsyacclex.fs --unicode --lexlib Internal.Utilities.Text.Lexing  fsyacclex.fsl ', CurrentDirectory='/auto/users/robnea/dev/tmp/FsLexYacc/src/FsYacc', Native error= Cannot find the specified file
@JanBessai
Copy link

Not setting fs(lex|yacc).exe executable is actually correct, because just like jars need java they need to be executed by mono. I think FsLexYacc.targets should do something along the lines of

<Choose>
    <When Condition="('$(OS)' != 'Windows_NT')">
        <FsYaccToolExe>mono $(FsYaccToolExe)</FsYaccToolExe>
    </When>
</Choose>

However, I'm not sure of the exact syntax and location.

@rneatherway
Copy link
Author

Ordinarily I would agree with you, but mono's implementation of Process.Start actually knows to handle this case specially and uses mono to invoke the .exe:

https://github.com/mono/mono/blob/master/mono/io-layer/processes.c#L806

Sadly the implementation still requires that the file be executable:

https://github.com/mono/mono/blob/master/mono/io-layer/processes.c#L784

@JanBessai
Copy link

Ah ok. Seems this is a nuget problem, because cloning the FsYacc project and building it creates .exe files with appropriate permissions in bin/.
I've added the following hack to the FAKE build.fsx of my own project in order to fix this for all dependencies (including others which suffer from the same problem):

Target "FixExecPermissions" (fun _ ->
    if isUnix then
         let setExecutable f =
             match f.ToString() with
                 | EndsWith ".exe" ->
                     System.Diagnostics.Process.Start("chmod", "+x " + f.ToString())
                     |> ignore
                 | otherwise -> ()
         recursively ignore setExecutable (directoryInfo "packages")
)

"Clean"
  ==> "RestorePackages"
  ==> "FixExecPermissions"
  ==> "AssemblyInfo"
  ==> "Build"
  ==> "RunTests"
  ==> "All"

@rneatherway
Copy link
Author

After this issue I submitted a PR to mono so that it still launches .exe files without +x. Happy to report it's now been merged (mono/mono#1081) so I think we can close this.

@kkm000
Copy link
Member

kkm000 commented Jan 22, 2015

Thanks for checking!

@kkm000 kkm000 closed this as completed Jan 22, 2015
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

3 participants