Skip to content

kurt/helios/unified-make-file #127

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

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

livingkurt
Copy link
Collaborator

No description provided.

…multiple categories. Updated task list to display selected categories.
@Unreal-Dan
Copy link
Collaborator

So the main thing that I notice is there is no copying of the files into the root directory after they are built.

For example, say I download this project, then I run:

make pngs

I would kinda expect the results of this to land in the current directory I am in, that's usually how make works (makes something in the folder you're in)

But in this case the pngs will end up in the cli folder or whatever.

Same with all the binaries, make lib, make cli, make embedded, make wasm, they all just end up putting the result file in the location where it gets built.

This is fine, but I guess what I'm saying is this file isn't very useful because you still have to cd around to get the stuff that was made.

Also, if you have something like 'make all' it really should make everything -- embedded, lib, cli, all together. Then you can package all of the binaries that are produced into a single zip for archiving purposes.

In order to fix your build so that you can compile different archs beside each other you just need to setup an intermediate directory for the object files the compiler produces -- each architecture/platform needs it's own intermediate directory, like say HeliosLib/avr/.o or HeliosLib/x64/.o

This doesn't need to be done, just explaining how in case you want to implement that. All of this stuff is just suggestions you don't have to take any of it too seriously

…t. Updated default target to build all components, improved clean target to remove artifacts, and added a new package target for zipping binaries.
… and improve object file management. Added architecture-specific build directories, updated object and dependency file paths, and enhanced clean targets to remove build artifacts. This streamlines the build process and ensures consistency across the Helios project.
…file copying. Updated commands to ensure all files are copied without error redirection, improving clarity and reliability in the build process.
…ing. Removed unnecessary error suppression, ensuring clarity in file copying. Added checks for WebAssembly compiler availability in both main and sub Makefiles, enhancing reliability during the build process.
…d clarity. Updated paths for output files, ensuring all components direct their outputs to a unified location. Enhanced clean targets to remove output directories, streamlining the build process across the Helios project.
…ed the target name from 'HeliosLib.js' to '$(FINAL_WASM_TARGET)' and ensured the output file is generated correctly, enhancing clarity in the build process.
…d clarity. Updated paths for output files, ensuring all components direct their outputs to a unified location. Enhanced clean targets to remove output directories, streamlining the build process across the Helios project. Removed obsolete scripts and patterns to simplify the codebase.
…test numbers from filenames. Removed unnecessary checks for file existence and improved clarity in test number extraction logic.
…e test directory structure. Adjusted paths in create_test.sh, export_tests.sh, import_tests.sh, record_test.sh, and record_tests.sh to point to the new output directory, ensuring consistency across test execution.
… new targets in Makefile for creating, exporting, and importing tests. Updated paths in test scripts to ensure consistency and clarity, allowing for relative directory access from the HeliosCLI context. This streamlines test creation and management processes.
…rgets to use the 'make -C' command for improved clarity and consistency in running tests from the Helios CLI directory. Removed unnecessary subshells for a cleaner Makefile structure.
…relevant test files are tracked in the repository.
Copy link
Collaborator

@Unreal-Dan Unreal-Dan 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 definitely a lot of changes, looks like you're doing a good job though. If you have any questions or if anything doesn't make sense let me know, I'm obviously quite forgetful sometimes about stuff.

I will try to sit down and do some better review and we can plan a call to get this merged


# Build and Output directories relative to this Makefile
BUILD_DIR = $(ARCH)
OUTPUT_DIR = output
Copy link
Collaborator

Choose a reason for hiding this comment

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

output must also be arch-specific, otherwise say you have x86/x64 you can't build them side by side.

Either the binary name or the output folder needs to reflect the arch.

You could do away with output/ entirely and just dump the binary in the arch directory with the object files, that's kinda fine too.

OBJS=\
$(SRC:.cpp=.o) \
# Separate source files by directory
HELIOS_SRC = $(shell find ../Helios -type f -name '*.cpp')
Copy link
Collaborator

Choose a reason for hiding this comment

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

I admit I've let you flail around a bit with this because I've been too busy to give you proper direction.

You've done an amazing job so far with my half-assed comments, I commend you.

So what would normally happen in this case is you wouldn't build the helios src files with this makefile, like I said this is the spaghetti you don't really want.

This makefile only really needs to track it's own sources and object files, then in order to get HeliosLib into HeliosCli you need to turn HeliosLib into a true lib and link the library in this makefile

The Makefile in HeliosLib/ needs to be able to produce a static library out of the code there, on linux this looks like HeliosLib.a or something like that.

The reason that I never really bothered with this part is because it doesn't exactly matter but now that you're fixing these makefiles we might as well solve the problem.

Here is an example makefile that produces a static lib by using 'ar' to combine all the .obj files together and produce the .a:

# Example Makefile section

# Source and output definitions
SRCS := file1.cpp file2.cpp file3.cpp
OBJS := $(SRCS:.cpp=.o)
LIB  := libmylibrary.a

# Compiler and archiver
CXX  := g++
AR   := ar
CXXFLAGS := -O2 -Wall -std=c++17

# Target: build static library
$(LIB): $(OBJS)
	$(AR) rcs $@ $^

# Rule to compile .cpp to .o
%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean target
clean:
	rm -f $(OBJS) $(LIB)

I just grabbed this from gpt the part you would be adapting would be the $(LIB): $(OBJS)

That would be like:

LIB = HeliosLib.a

And this would also be able to build for x86 or x64....

But here's where things get a little funky...


The Embedded Build

Yeah, so, HeliosEmbedded also does this same thing of building the src files from the other folder... but that's because I don't know if using ar to make an archive/static lib out of helios then linking that into the HeliosEmbedded entrypoint would cause different results in optimizations for size.

Like, if you build a static library the ar tool doesn't discriminate which functions/things to keep. There's no optimization in terms of trimming away useless functions when making a static lib.

I don't know if the optimizer would work the same for the avr build if we simply linked HeliosLib.a (in avr arch) with the main.o for the embedded entrypoint.

In theory, it should work the same... but I didn't feel like testing it in case it ended up being a waste of time.

Anyway sorry if this is a bit of a rant my brain is cooked today but I wanted to try and help you out.

Copy link
Collaborator

@Unreal-Dan Unreal-Dan May 1, 2025

Choose a reason for hiding this comment

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

to be a bit more clear, it absolutely should work fine to build the static lib with avr arch and just link it with the heliosembedded main.o -- I was probably more lazy than worried it wouldn't work

the ar tool is just archiving, ie putting all the obj files together into a single archive file. Linking a .a I believe follows the same procedure as .o files.

Here I got some more gpt crap:

project/
├── lib/
│   ├── Makefile      # Builds libmylibrary.a
│   ├── file1.cpp
│   ├── file2.cpp
├── app/
│   ├── main.cpp      # Uses libmylibrary.a
│   ├── Makefile      # Builds the binary

So the lib/Makefile is like HeliosLib like the one in the above example I gave.

Then the app that pulls on the lib is like HeliosCli or HeliosEmbedded:

# app/Makefile

# Compiler setup
CC := g++
CXXFLAGS := -O2 -Wall -std=c++17

# Output binary
TARGET := myapp

# Source files
SRC := main.cpp
OBJ := $(SRC:.cpp=.o)
DFILES := $(SRC:.cpp=.d)

# Static library (exact path, not -l syntax)
LIBS := ../lib/libmylibrary.a

# Combined dependencies
DEPS := $(OBJ) $(LIBS)

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(DEPS)
	$(CC) $(CXXFLAGS) -o $@ $(OBJ) $(LIBS)

%.o: %.cpp
	$(CC) $(CXXFLAGS) -MMD -c $< -o $@

# Auto-build any .a static lib from its folder
%.a:
	$(MAKE) -C $(dir $@) $(notdir $@)

clean:
	rm -f $(OBJ) $(TARGET) $(DFILES)
	$(MAKE) -C $(dir $(LIBS)) clean

# Auto-include generated dependency files (ignore missing ones)
-include $(DFILES)

This above example is slightly tailored, it uses some of the tricks I've shown like the DFILES and it also uses a trick to build the static lib:

%.a:
	$(MAKE) -C $(dir $@) $(notdir $@)

This target catches all libs and runs make in the directory of $@ (so the libs folder) on the lib name.

So in Helios for example it would run:

make -C ../HeliosLib HeliosLib.a 

Then ../HeliosLib/HeliosLib.a can simply be put at the end of the compiler command like

$(LD) $(OBJS) -o $@ $(LIBS)

which would be:

ld main.o -o helios_cli ../HeliosLib/HeliosLib.a

you can interchange LD with g++ in the above example btw. g++ understands if it receives obj files it will just passthrough to LD.

# catch-all make target to generate .o and .d files
%.o: %.cpp
# Rules for building object files
$(BUILD_DIR)/Helios/%.o: ../Helios/%.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

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

so in theory this shouldn't exist, all building of HeliosLib stuff should be in the makefile that is in that folder

# Build and Output directories relative to this Makefile
BUILD_DIR = $(ARCH)
OUTPUT_DIR = output
FINAL_LIB_TARGET = $(OUTPUT_DIR)/helios_lib.a
Copy link
Collaborator

Choose a reason for hiding this comment

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

oh neat, a static lib, LOL

@@ -94,10 +105,9 @@ TESTS=\

# target files
ifdef WASM
TARGETS=HeliosLib.js \
helios.a
Copy link
Collaborator

Choose a reason for hiding this comment

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

ohhhhhhh I already had a helios.a being generated, well I'm ahead of myself then

else \
echo "WebAssembly compiler (em++) not found, skipping WASM build."; \
mkdir -p $(OUTPUT_DIR); \
touch $(FINAL_WASM_TARGET); \
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are these here? If it's skipping the wasm build in this section why mkdir and touch files?

# the following environment variables need to be used in the component Makefiles:
#
# 1. ARCH - Target architecture (avr, x64, wasm)
# 2. BUILD_DIR - Location for object files
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the way you solved ARCH with the environment variable was quite accurate and similar to how it's solved normally.

However, BUILD_DIR I think is wrong, all the makefiles should simply generate a build dir relative to their location -- they shouldn't be dumping files elsewhere just because an env var switched the output folder.

HeliosLib/x86/*.o
HeliosLib/x86/HeliosLib.a

HeliosCli/x64/*.o
HeliosCli/x64/helios_cli

The makefile for HeliosCli would link the *.o in this folder + ../HeliosLib/$(arch)/HeliosLib.a

Then quite simply as a prerequisite to build any HeliosCli or HeliosEmbedded, the first step of the build would be something like (off the top of my head):

env ARCH=$(ARCH) make -C ../HeliosLib

So that HeliosLib is up-to-date before it attempts to build the binary that links with it.

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.

2 participants