primaryodors / primarydock

PrimaryOdors.org molecular docker.
Other
6 stars 4 forks source link

make is rebuilding all of the targets every time. #41

Closed electronicsbyjulie closed 2 years ago

electronicsbyjulie commented 2 years ago

Whenever I run make, it rebuilds everything, even if I didn't change any of the code.

objarni commented 2 years ago

Curios. And a point towards CMake: it generates a great makefile for us (with progress bars, possibility for parallell compilation etc.) and with a much cleaner / more declarative style of expression. Here's how you build a repo that is based on CMake:

# it is customary to have a separate folder for the build when using cmake. Clean!
mkdir build
cd build
# generate makefile from folder above build/ - this is where the magic happens. A Makefile will be created in build/
cmake ..
make  # build repo

The command cmake .. only has to be run when source files are added/remove from repo, not every time. Ordinary workflow is just as today: run make.

I am making progress on gcov / code coverage without CMake however, and our "regression system" is getting better by the day so I'm indecisive here.

What's your take on CMake vs makefile?

objarni commented 2 years ago

Hello world example of cmake in action https://lappweb.in2p3.fr/~paubert/ASTERICS_HPC/2-2-100.html

electronicsbyjulie commented 2 years ago

If it would still be possible to compile podock in environments where CMake is unavailable, then this sounds perfect!

objarni commented 2 years ago

In theory, it would - if we include Makefile that CMake would generate in the repository.

However, I would say it's not recommended, as CMake checks the system for compilers and other tooling, tweaking the generated Makefile to suit the system it is run in. Do you know the target systems' compiler etc.?

electronicsbyjulie commented 2 years ago

For the web host, here's the version info. It wouldn't be ideal to tie the makefile to a specific target environment, but it could be okay in the short term. The current makefile compiles perfectly.

$ make --version
GNU Make 4.2.1
Construit pour x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
Licence GPLv3+ : GNU GPL version 3 ou ultérieure <http://gnu.org/licenses/gpl.html>
Ceci est un logiciel libre : vous êtes autorisé à le modifier et à la redistribuer.
Il ne comporte AUCUNE GARANTIE, dans la mesure de ce que permet la loi.
$ g++ --version
g++ (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Part of my philosophy with podock arises from having been unable to compile AutoDock. As far as I could tell it can only be built with CMake which meant it would be unavailable on the remote server. Also my attempts to compile it locally (to add parameters that don't come with the software) were met with roadblocks. It worked out anyway since AutoDock doesn't do path based docking or break down its output by residue/by binding type, so it made sense to write my own. But with the intent that mine would be easy to build and easy to configure.

objarni commented 2 years ago

I can sympathize with your philosophy. And I would also be suprised if "sudo apt install cmake" wasn't possible on the server.. At least if you are admin on it.

BUT: I think we should take the smallest step here, and fix the makefile. I investigated a bit what is going on, and it's about the OBJDIR being 're-created' when the all target is run; meaning e.g. obj/point.o becomes 'older' than it's dependency (OBJDIR), which is just not true more than in the 'modified timestamp' sense. Make is really naive/simple in that sense: the only thing that is happening during a 'make' invocation is the checking of modified timestamp on the target, and if any of the dependencies are newer than the target, the target build steps are performed:

test/point.o: $(OBJDIR) src/point.h src/point.cpp
    STEPS

If any of the right hand side 'entities' have a later time stamp (has been modified since the point.o file was built), STEPS will be performed.

Now, since $(OBJDIR) target is always invoked by all target (not sure why), and mkdir apparently 'touches' the obj/, point.o will always be re-built. The same is true to every .o file, and, by cascading effect, everything will be rebuilt by make all.

To my mind, this is a bug in mkdir, but we'll have to figure out a way around it. One way, which feels disatisfying, is to create the obj/ and bin/ folders in the repo with some empty text file, so that we take the folders out of the makefiles responsibility. A hack, but will work (I think).

electronicsbyjulie commented 2 years ago

I don't have sudo access on the remote server.

The text file is a possible solution. $(OBJDIR) is part of all so that the first time a user builds the code, it will create the folders - a howto page on the internet said to do that. (I know, haha.) Another possibility would be a separate first time target that the user would have to make before they make all. Maybe there's a way to put a shell if statement to check if the dir already exists before calling mkdir?

objarni commented 2 years ago

Nice work on the makefile! all does not rebuild anymore, and from some random testing of e.g touch src/classes/molecule.cpp and the like, it does only rebuild what needs to be rebuilt!

Do you think we could close this, or any more concern?

electronicsbyjulie commented 2 years ago

Thank you! Yup, this one appears to be completed.