-
Notifications
You must be signed in to change notification settings - Fork 2
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][MISC] Rewritten all Makefiles for efficiency and correctness #269
Conversation
- Also added new top-level Makefile
- protos moved back to original location net_handler/protos - top-level Makefile has all and clean - top-level Makefile_defs included by each Makefile - resulting lower-level Makefiles are (relatively) simple
- tests/Makefile works more efficiently than before - Updated runtime script to reflect changes - Fixed some compiler warning bugs in test/test.c
- decided top-level Makefile not needed; just use the root runtime script
aa2c223
to
1b8a3a0
Compare
- Removed a bunch of irrelevant lines to reduce confusion - Having the SSH URL for protos as the module might cause problems - ... when building Runtime on Raspberry Pis so I reverted it
1b8a3a0
to
c628ca4
Compare
- CI format job was causing issues, wrote own simpler format script
- Bring in changes from Device Reset fixes
- Some tests are spewing -Wno-format errors that should be suppressed - To address, added $(LIBS) to .o -> .c rule in tests/Makefile - Cython is complaining about not being able to import log levels - To address, renamed runtime.pxd -> studentapi.pxd
A lot of small extra cleanup / QOL items were added in this PR. The
I also managed to silence some formatting warnings in the compilation that was cluttering our CI output, and write our own formatting bash script specific to Runtime that is much much simpler than the Python script we had before. The test script now can take I also deleted the |
9df5149
to
8e142fc
Compare
…gument - Previously, you had to write ./runtime test integration/tc_150_1 - Also deleted provisioning and installation scripts for Runtime - Updated help text on root runtime script
8e142fc
to
c82d403
Compare
rm -f $(patsubst %.o,%.d,$(OBJS)) | ||
rm -f $(BIN)/$(TARGET) | ||
|
||
-include $(patsubst %.o,%.d,$(OBJS)) |
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.
What's this do?
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.
This is a little complex. So basically the -MMD -MP
compiler flags that I added to CFLAGS
at the top of Makefile_defs
tells the compiler that, when compiling a source file into an object file, to also create a "dependency file" for that object file. The dependency file is in the format of a Makefile and basically lists out all of the sources and header files that the compiler needed to look at in order to generate the object file. The dependency file has the same name as the generated object file, except with a .d
extension. So we include all of the .d
dependency files associated with the object files needed to make this executable with this line. Thus, when we try to compile a specific object file, make
will know which sources and headers that object file is dependent on, and if any of those are newer than the object file we are trying to make, then the object file will be recompiled.
Here are a couple of good articles explaining it:
https://nathandumont.com/blog/automatically-detect-changes-in-header-files-in-a
https://stackoverflow.com/questions/8025766/makefile-auto-dependency-generation
http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
Makefile_defs
Outdated
THIS_DIR = $(strip $(shell pwd | xargs basename -z)) | ||
|
||
COMPONENT_DIRS = dev_handler net_handler executor network_switch shm_wrapper runtime_util logger # list of runtime component directories | ||
OBJ_SUBDIR = $(foreach dir,$(COMPONENT_DIRS),$(OBJ)/$(dir)) # list of subfolders in $(OBJ) for runtime object files |
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.
small nit: suggest putting the in-line comments above the line of code for easier readability
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.
agreed, changed!
@@ -19,7 +25,7 @@ | |||
setup( | |||
name="Student API", | |||
ext_modules = cythonize([ | |||
Extension("studentapi", sources=sourcefiles, libraries=libraries) | |||
Extension("studentapi", sources=sourcefiles, include_dirs=includedirectories, libraries=libraries) |
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.
Why are we adding another parameter, include_dirs here?
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, yes. So when Cython generates ("cythonizes") the studentapi
extension (which is how the StudentAPI is currently implemented--perhaps this will change when @BrandonWong14 takes a crack at it later this summer), it needs to know where to find the header files in its C code. Previously, we used quotations to include header files in the student API (i.e. #include "some_header.h"
) but since i took all of those away and changed them to angle brackets (i.e. #include <some_header.h>
) for better readability, I had to specify which directories to look for these headers in this line to create the Cython package.
The official Cython documentation has this page describing how it works.
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.
Looks good!
All the Makefiles are in similar formats and they are much more readable than before.
It wouldn't be too difficult to create another Makefile following your format if we were to start working on a new directory.
Thanks for cleaning up the codebase Ben :D
# specify the target (executable we want to make) | ||
TARGET = dev_handler | ||
|
||
.PHONY: all clean $(TARGET) |
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.
Ben: "basically it tells make that the thing listed after .PHONY is not a real file; in this case we don’t actually make a file called all, clean, or dev_handler (we make a file called ../bin/dev_handler)
basically it prevents make from redo-ing commands, like say we want to have make dev_handler build ../bin/dev_handler. if we don’t declare dev_handler as .PHONY then when you run make dev_handler it will always try to look for a file called dev_handler, which will never exist (cuz really the file is ../bin/dev_handler ) so it will run the compilation command again when it doesn’t need to"
Adding it here for future reference.
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.
Just to clean up this message a bit since that was something I hastily wrote in Slack:
If you're completely confused, read our wiki page on make
here.
But in short, this Makefile contains the targets all
, clean
, and dev_handler
. However, none of these targets are real files (there is no file at runtime/dev_handler/all
, runtime/dev_handler/clean
, or runtime/dev_handler/dev_handler
). That last one might be a bit confusing--the dev_handler
executable is located in runtime/bin/dev_handler
, so from the perspective of the directory that this Makefile is in, the path is ../bin/dev_handler
.
Thus, if we just left the Makefile with these three targets, each time we ran make all
or make clean
or make dev_handler
, it would try to find a file called all
, clean
, or dev_handler
, respectively, fail to find the file (since we never make a file with that name), and always run the recipe (which is not what we want to do!). We only want to run the recipe if there is something to be made.
Thus, we tell make
that these three special targets are not real files by labeling them as .PHONY
. Thus, when we do make dev_handler
, it will it won't automatically build everything just because it can't find the dev_handler
file (which will never exist).
In the past, our builds / Makefiles had two problems:
./runtime build
again, and not have all dependent files be rebuilt again.This PR fixes these issues by:
-MMD
and-MP
compiler flags to autogenerate dependency files for each object fileThis does make our Makefiles somewhat more complex, however, I tried my best to keep the number of syntax features to a minimum while still getting the job done in a more or less general way.
In addition to the Makefile changes, I fixed / cleaned up / added a few things:
#include
of Runtime headers to use angle brackets instead of quotes with relative path names (better readability!) since our Makefiles are able to support that nowdev_handler.c
anddev_handler_message.c
, as well as incorrect use ofprintf
intest.c
.gitignore
so as to only ignore the necessary folders / files; we used to have a copypasta.gitignore
from somewhere that had way too many entries and might lead to confusion for new membersrun_clang_format.py
script and replaced it with a much simpler, in-house script that I wrote in bash that does basically the same thing. Run a check with./runtime format check
and fix code to comply with the standard with./runtime format fix