Skip to content

Conversation

@everythingfunctional
Copy link
Member

No description provided.

@everythingfunctional
Copy link
Member Author

I think I might need some help from somebody who understands Windows a bit better to help me with the issue there. I'm guessing either something with the absolute paths is screwing up make, or the environment variables aren't working properly. I'm leaning towards the former, but I don't have access to a Windows machine to test it with at the moment.

Copy link
Member

@certik certik left a comment

Choose a reason for hiding this comment

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

I think this looks great. We have to fix the Windows error, but otherwise that's what we talked about.

@@ -0,0 +1,9 @@
INCLUDE_FLAGS = $(addprefix -I,$(INCLUDE_DIRS))

$(BUILD_DIR)/libmakefile_complex.a: $(BUILD_DIR)/wrapper_mod.o
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to prefix all the environment variables with FPM_, so:

  • FPM_INCLUDE_FLAGS
  • FPM_BUILD_DIR

etc.

Copy link
Member Author

Choose a reason for hiding this comment

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

The ones I used are actually the standard environment variables for Makefiles. You (almost) can use an empty Makefile and these would actually work. We can use prefixed variables, but it's one extra difference from what a lot of people will already have and be used to.

Copy link
Member

Choose a reason for hiding this comment

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

This seems fine to me - FC and FFLAGS are standard Makefile variables - and I think we should be minimising the amount of changes people have to do to their Makefiles for compatibility.

with_makefile = { path = "../with_makefile" }

[library]
source-dir = "src"
Copy link
Member

Choose a reason for hiding this comment

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

This is the default, isn't it? So it can be removed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right now if you have a [library] section, it has to contain source-dir. I can make it optional, I just haven't done that yet.

@certik
Copy link
Member

certik commented Jun 15, 2020

The windows error is:

# gfortran (for build/gfortran_debug/test/main.o)
# gfortran (for build/gfortran_debug/test/runTests.exe)
 Hello, from test!
mingw32-make: *** No rule to make target 'D:\a\fpm\fpm\test\example_packages\with_makefile\build\gfortran_debug\with_makefile\libwith_makefile.a'.  Stop.
mingw32-make: *** No rule to make target 'D:\a\fpm\fpm\test\example_packages\makefile_complex\build\gfortran_debug\with_makefile\libwith_makefile.a'.  Stop.
mingw32-make: *** No rule to make target 'D:\a\fpm\fpm\test\example_packages\makefile_complex\build\gfortran_debug\makefile_complex\libmakefile_complex.a'.  Stop.

@@ -0,0 +1,9 @@
INCLUDE_FLAGS = $(addprefix -I,$(INCLUDE_DIRS))

$(BUILD_DIR)/libwith_makefile.a: $(BUILD_DIR)/hello_makefile.o
Copy link
Member

Choose a reason for hiding this comment

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

I am guessing you cannot use a target like this on Windows.

Copy link
Member Author

Choose a reason for hiding this comment

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

I suspect it's the D: at the front. Make sees that as the end of the target name. can you put quotes around that in a makefile?

Copy link
Member

@milancurcic milancurcic left a comment

Choose a reason for hiding this comment

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

Looks great!

@certik
Copy link
Member

certik commented Jun 15, 2020 via email

@everythingfunctional
Copy link
Member Author

I am worried it's going to mess up buildsystems. Cargo is not using such variables either.

I'm not sure I understand. The environment variables are only set while fpm is running. Can you give me an example of a situation that might break?

@certik
Copy link
Member

certik commented Jun 15, 2020

I'm not sure I understand. The environment variables are only set while fpm is running. Can you give me an example of a situation that might break?

I don't know for sure, but an example would be an autotools build system, that reads these common environment variables, and if they are set by fpm it might break the build. I've definitely seen build systems where things break if you set these variables. So then the user would have to unset them before running autotools.

It seems that prefixing them with FPM_, it would ensure that as we expose more variables in the future, things that already work will continue working.

However, one variable I would set automatically, and that is CMAKE_PREFIX_PATH. I think Spack does it, and that makes any CMake project to easily find all the fpm dependencies without the user having to do anything.

I think your idea is to follow a similar philosophy for raw Make also.

Also as a documentation, it's hard to tell from looking at the script who sets the BUILD_DIR variable. But if it is FPM_BUILD_DIR, then it is clear that it is set by fpm.

I don't know. Let's try this, and keep our options open to possibly prefix it if we run into problems?

@everythingfunctional
Copy link
Member Author

My thinking is that if having those environment variables set means your build script doesn't work, that your build script isn't compatible with fpm, and you need a different one for fpm to use. Since the variables aren't persistent after fpm is done running, it won't break existing build systems. They can coexist side by side.

If we use prefixed variables, then users are practically guaranteed to have to write a new build script for fpm to use. If we use commonly used ones, there's a chance their existing one might actually work.

I agree, let's see how this works out, and if we have to change it later, we can.

I'm not all that familiar with CMake, but we can always do different things for different build tools when we add support for them.

Copy link
Member

@LKedward LKedward left a comment

Choose a reason for hiding this comment

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

This is great @everythingfunctional; will really help bring compatibility to existing packages!

Regarding environment variables, adding a prefix actually means more changes to existing Makefiles since I would want to also maintain the existing Makefile behaviour (with FC etc.).

My only minor nitpick is with the compounding of Makefiles and build scripts / executables in the fpm.toml definition - I think we should try to keep the fpm.toml options simple and explicit, and avoid options with 'implicit' rules of the form "OPTION does A except if it contains B then it does C".
I would prefer there be an option to specify a build script and a separate mutually exclusive option to specify a Makefile (and possibly a third for cmake).

PACKAGING.md Outdated
* `FC` - The Fortran compiler to be used
* `FFLAGS` - The flags that should be passed to the Fortran compiler
* `BUILD_DIR` - Where the compiled files should be placed
* `INCLUDE_DIRS` - The folders where any dependencies can be found
Copy link
Member

Choose a reason for hiding this comment

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

The trailing 'S' implies multiple folders can be specified - is this done in a system-dependent manner using colon/semicolon separators? If so, it's worth mentioning that here. (I had thought multiple include paths had to be specified with multiple -I flags.)

Copy link
Member Author

Choose a reason for hiding this comment

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

They are space separated. So yes, that should be mentioned here, and it is then necessary for your build script to turn this list into the appropriate flags for the compiler(s). I'll add this info.

Comment on lines +691 to +692
Additionally, script will be called with the name of the archive (`*.a` file)
that should be produced as the command line argument.
Copy link
Member

Choose a reason for hiding this comment

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

Is this a full path to the archive file including BUILD_DIR or just the filename?
Perhaps worth mentioning explicitly that this is only for scripts not Makefiles to avoid confusion.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is the full path. And it actually is also for Makefiles. This is the target specified, so your Makefile doesn't necessarily have to have the library as the default target.

Copy link
Member

Choose a reason for hiding this comment

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

Ah I see, that makes a lot of sense. I would suggest also stating that explicitly in the following section about invoking make.

@everythingfunctional
Copy link
Member Author

My only minor nitpick is with the compounding of Makefiles and build scripts / executables in the fpm.toml definition

I hadn't really thought about it that hard. It's worth considering. Usually I'd agree, but somehow this seemed simpler from a user and documentation stand point. If you have a custom build process, there's one way/place to specify it, and fpm just knows what to do with it.

@milancurcic or @certik , do you guys have an opinion on this?

@certik
Copy link
Member

certik commented Jun 15, 2020

These are all really tough questions with good arguments on both sides. My only suggestion is to be open and open to change things if things don't feel right. I think the way forward is to insist that we are still in a prototype phase, and so things can (and will) change --- let's put this in bold in the README? And in a prototype phase, let's just try it, and get more experience, and be ready to change things. Only after we declare we are in production, we should be backwards compatible as much as possible.

In general, I was hoping that fpm would simply execute the "script" as an executable, and always pass the same environment variables. I feel it is ok for fpm to know how to execute the script properly, so a bash script using bash, a Xonsh script using Xonsh, Make file using make, and an executable as an executable.

I think it is absolutely ok for users to write a short build script. You will have to do it anyway for cmake projects.

@milancurcic
Copy link
Member

milancurcic commented Jun 15, 2020

I don't see issues with this. Like @certik said, let's try it and we can revise if there's need for it. We can't think of all correct answers ahead of time without trying things first in practice.

Minor nit pick: As a user I didn't expect that for using make the build_script value would be Makefile or *.mk. build_script = "make" or build_script = "make target" seems more intuitive, because that's what I would've typed otherwise. However, this is also perhaps problematic because neither Makefile nor make are scripts (Makefile is a specification file and make is a command/tool). Perhaps a build_command parameter would be more appropriate if both arbitrary scripts and make are to be invoked with it.

@certik
Copy link
Member

certik commented Jun 15, 2020

One issue with build_command is that we need to specify the shell. So it could be Bash on Linux/macOS and PowerShell on Windows. Simple commands like make target would work in both. More advanced things, such as referencing an environment variable will not work cross-platform. Essentially the issue is a lack of cross-platform shell.

Rust / Cargo goes around this by simply writing the "build script" in Rust itself, thus making it cross-platform.

I think there is a huge need for a cross-platform native shell. We even started one: https://github.com/xonsh/minixonsh (Xonsh itself is one, but being a Python program, it has the typical Python issues related to distribution and speed).

But until there is one (and well supported), I think we should not just pick one and require it.

So given all of this, the two option are:

  1. build_script would be directly executed in Bash / PowerShell, so you have to use a subset that works in both, such as make or make target. Or bash my_buildscript.sh.

  2. build_script points to a script or executable that gets executed. So Makefile gets executed via make, as fpm knows this.

I still think 2. seems better.

But overall, I don't know what the best way forward is. So let's just try something to get moving, and iterate.

@everythingfunctional
Copy link
Member Author

I think there will be some packages which are just not supported on all platforms, and that's ok. As a community we can encourage that and provide support when we're able, but that's going to be a big hurdle in some instances.

As everybody seems to agree, let's try this PR out and see how it goes.

@everythingfunctional everythingfunctional merged commit 410537b into fortran-lang:master Jun 16, 2020
@everythingfunctional everythingfunctional deleted the MakefileSupport branch June 19, 2020 02:20
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

Successfully merging this pull request may close these issues.

4 participants