-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Add a :make compiler #4134
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
Add a :make compiler #4134
Conversation
It looks like a good point starting point. Don't forget to call build_structure too. There is a very detailed set of outcomes in comeonin too: https://github.com/elixircnx/comeonin/blob/master/mix.exs |
@josevalim thanks for the pointer to comeonin, lots of good strategy in its mixfile :). I have a design question: we could either provide an option like [...,
make_makefile: (if match?({:win32, _}, :os.type()), do: "Makefile.win", else: "Makefile")] and we'd run Wdyt? |
I think we could do both. The question is, should we support non-conventional makefiles for |
Also, the target also changes depending on the platform. :( |
Yes the target changes, but users could rely (not every time but most of the time of course) on the fact that |
This is ready for review. I added the following options:
(PS sorry it took me so long to work again on this) |
|
||
args = args_for_makefile(exec, makefile) ++ targets | ||
|
||
exit_status = File.cd!(cwd, fn -> cmd(exec, args) end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can pass a cd
option to System.cmd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, awesome :) Fixed in the next commit!
end | ||
|
||
defp build(config) do | ||
makefile = Keyword.get(config, :make_makefile, :default) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also expose make_executable
? The default is the OS lookup we perform. :)
This looks really good, I have added just one last comment. :) |
exec = executable_for_current_os() | ||
|
||
args = args_for_makefile(exec, makefile) ++ targets | ||
exit_status = cmd(exec, args, cwd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be cleaner if we case on cmd/3
right away:
case cmd(exec, args, cwd) do
0 -> :ok
exit_status ->
build_error(exec, exit_status, error_msg)
end
Hey @lexmag and @josevalim, I should have fixed all the stuff both of you mentioned (and added the |
Wonderful. 💛 |
Looks like Travis makes tests to fail, we need to find a way to skip "Entering directory" and "Leaving directory" output. |
@lexmag oops, you're right. What if we check the captured io with |
Maybe it would be nice if there were a |
Sorry for the long silence period! @tuvistavie I guess we could have |
A few comments / questions:
|
Thank you @riverrun. I will verify 1. 2 can be fixed by adding a manifest. Which particular point about 3 do you think we should incorporate? |
About number 3, that's still under discussion. I'll get back to you on this thread soon. |
So, more information about the issues on Windows, and the link I cited two days ago: With comeonin, I've had several issues with developers finding it difficult just to set up the C environment on Windows. I usually advise them to install Visual Studio, after which the developer then has to follow this rather complex process. One issue particularly relevant to this PR is that, apparently, you need to run the command Some developers have reported that they also need to set the PATH manually, and other developers have had issues where the build fails because they are not using the correct prompt (even within Visual Studio). We're trying to see if using gcc on Windows is a bit easier to work with. I presume that this will mean that we need to run |
Thank you so much @riverrun. I believe if you want to use make, you would depend on something like MinGW? We have setup instructions for it here: https://github.com/elixir-lang/elixir/wiki/Windows |
Hello, I would like to help out with the nmake portion of this pull request. Also I would really like to see it become available so that projects start using it. What's next to get this done? |
Hello again, I have made some changes to compile.make.ex that can be seen here: https://github.com/jpmec/elixir/tree/make-compiler-nmake I can make a pull request for this if you wish, or you can just cut and paste (there really isn't that much there). From my previous research into using nmake with comeonin, the key to nmake was setting environment variables before calling nmake. Some have suggested opening the VS command prompt, but IMHO this option sucks. For example, I like Powershell and I don't want to have to open a special command prompt just to compile my elixir and be forced to use that command prompt (especially when the only magic behind it is setting some env variables when it is opened). I've made a project here that can get the environment variables needed for nmake So if we expose the make_env in the configuration, this will make it very easy to support nmake, or any other "special" compiler that needs some environment variables set before it can operate properly. Anywho, hope you will consider it |
Hey @jpmec, I'm not sure about your solution. As far as I understand, you're trying to have some kind of "with this env" functionality by getting the env, modifying it and running make, then resetting it to its previous state. Your solution doesn't work properly though: System.get_env["FOO"] #=> nil
env = System.get_env
System.put_env(%{"FOO" => "bar"})
System.get_env["FOO"] #=> "bar"
System.put_env(env)
System.get_env["FOO"] #=> "bar" As you can see, you can only reset the values of existing variables; any new variable you introduce in That said yes, we can support setting a make environment. I'm afraid too many make options are starting to pop out, I fear this is a smell that we're doing something wrong. Wdyt @josevalim, @lexmag and @ericmj? |
Environment variables can be passed to `System.cmd/3` as the `:env` option.
That would be the preferable approach.
|
@whatyouhide you've interpreted it correctly, and yes I saw that it would pollute the env with new environment variables :-(. The System.cmd approach is probably better to restore the env completely. I kinda agree about the "smell" for the compilers, but I don't know of an easy way to fix this. My desire would be to be able to plug in a compiler at my project mix level, so that the end user can wire up whatever compiler they need. However there is alot of change needed for that from what I could see. The approach you have done with the :make compiler fits the current pattern. I think the small change for the env would at least allow nmake to work, which would be a big win for Windows users new to elixir. I know that some like to use mingw instead of visual studio, so making sure that this can be configured at the top level is also definitely a need. How would you like to proceed? |
I've updated here I simplified by using @josevalim suggestion about passing in the opts of System.cmd/3. |
After testing a few different options with Visual Studio, I've updated the requirements page and the compiler for Comeonin. They now include a more straightforward way of getting set up on Windows. Regarding this PR, I think the error messages in the Comeonin compiler provide a lot of useful information when things go wrong, and I think we should make this information more accessible - either by having generic error messages in the Compile.Make file or by adding the information to the documentation somewhere. |
@riverrun @whatyouhide @jpmec I have been thinking about this. This PR is here for 4 months already and there are still at least 2-3 months before Elixir v1.3. Furthermore, we may need to push improvements quickly after Elixir v1.3 is out which may not suit Elixir's release schedule. What if we release this as a separate package, so we can iterate and continue improving this quickly, and by the time we are close to release Elixir v1.3, the package will be more stable and providing the sort of feedback that we require? If we all agree, I will start a new package called elixir_make with a compiler called elixir_make which we will use for now. Once we bring into Elixir and Elixir v1.3 is out, all you need to do is ditch the elixir_make dependency and use the make compiler directly (as long as you are Elixir v1.3 only). The advantage of providing a package is also that if you want to support earlier Elixir versions, it will also be able to do so. Thoughts? |
@josevalim this is what I did initially in https://github.com/whatyouhide/make_compiler, so I tend to agree. I stopped working on that when I opened this PR. José, if you create the package I can re open a PR similar to this there. |
I think that's great idea! |
Did you ever release any version for it, Andrea? José Valimwww.plataformatec.com.br |
@josevalim nope, #4082 was opened right after I pushed my library on GitHub so I never got around to publishing it to Hex (and I stopped working on it, so it's behind this PR feature-wise). |
So we can either create a new one or revamp that one, but since there was José Valimwww.plataformatec.com.br |
@josevalim I have no preference, mine can definitely be ditched (I can kill the repo off completely) as there's very little work there, I have absolutely no problem with that. Maybe elixir-lang/* will give it more credibility 😃, but it's your call. |
Yeah, I was mostly thinking about elixir-lang too. :) On Saturday, May 14, 2016, Andrea Leopardi notifications@github.com wrote:
José Valimwww.plataformatec.com.br |
@josevalim #makeithappen then! 👍 |
I will create the project soon and give you access so you can push your On Saturday, May 14, 2016, Andrea Leopardi notifications@github.com wrote:
José Valimwww.plataformatec.com.br |
@josevalim sounds good, I can try working on it if you want (I have time this weekend) and if you have a clear-ish API in mind (I don't 😛). |
I'm opening this PR to test the water regarding the make compiler mentioned by #4082. It doesn't support
nmake
and it's pretty barebones, but it could be a starting point. Here, just a couple of options are configurable::make_cwd
to choose the cwd for runningmake
, and:make_targets
for the list of make targets to be run. We could make other options configurable, like specifying aMakefile
. Also, right now everything thatmake
outputs is streamed to stdout, we could make that configurable as well (e.g.,:make_report_only_errors
or something similar).Wdyt?