premake-core
premake-core copied to clipboard
g++/clang++ not found while linking when installed in a custom location
I'm building on a Linux system (WSL2) that doesn't have gcc or clang installed in /usr. Instead, it's installed in my local project directory. I've added the following to premake5.lua:
bindirs { "path/to/gcc/bin" }
The relevant portions of my generated makefile are:
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
$(OBJDIR)/main.o: source/main.cpp
@echo $(notdir $<)
$(SILENT) $(EXE_PATHS) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
While building I get an error like:
/bin/sh: 1: g++: not found
I think the generated LINKCMD above should really look like:
LINKCMD = $(EXE_PATHS) $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
That is most likely Make not knowing where your C++ compiler is, not a bug in Premake. Is GCC/G++ on your path? Have you tried passing CXX as a parameter to make?
My understanding is that this is what the bindirs
instruction is for in premake. Is this not the case? Like because of the $(EXE_PATHS)
param in the generated build instruction, make is able to find the compiler to generate object files just fine. But because this is missing from the link command, it can't do the same for that step. I agree that I could fix this by doing something like:
PATH=/path/to/gcc/bin:$PATH make
But it doesn't seem like this should be necessary. Assuming I had GCC installed in the default location and a different version installed elsewhere that I was pointing to via bindirs
for this build, I'd be using a different version of G++ for the link step than I used to generate object files.
Can you share more of the generated makefile?
Makefile:
all: $(PROJECTS)
app: proj-test
proj-test:
ifneq (,$(proj_test_config))
@echo "==== Building proj-test ($(proj_test_config)) ===="
@${MAKE} --no-print-directory -C . -f proj-test.make config=$(proj_test_config)
endif
proj-test.make:
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LDDEPS +=
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
EXECUTABLE_PATHS = "_build/tools/gcc/bin"
EXE_PATHS = export PATH=$(EXECUTABLE_PATHS):$$PATH;
...
# File sets
# #############################################
GENERATED :=
OBJECTS :=
GENERATED += $(OBJDIR)/main.o
OBJECTS += $(OBJDIR)/main.o
# Rules
# #############################################
all: $(TARGET)
@:
$(TARGET): $(GENERATED) $(OBJECTS) $(LDDEPS) | $(TARGETDIR)
$(PRELINKCMDS)
@echo Linking proj-test
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
$(TARGETDIR):
@echo Creating $(TARGETDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(TARGETDIR)
else
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
endif
$(OBJDIR):
@echo Creating $(OBJDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(OBJDIR)
else
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
endif
...
# File Rules
# #############################################
$(OBJDIR)/main.o: source/main.cpp
@echo $(notdir $<)
$(SILENT) $(EXE_PATHS) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
-include $(OBJECTS:%.o=%.d)
ifneq (,$(PCH))
-include $(PCH_PLACEHOLDER).d
endif
From looking at the premake code, I found this for example, which injects the bindirs for the build step: https://github.com/premake/premake-core/blob/master/modules/gmake/gmake_cpp.lua#L257
But the LINKCMD
isn't given the same treatment, as you can see above. Maybe not a huge issue if this is C and you can link with ar, but potentially more of an issue for C++ when you typically link via the compiler.
I believe that bindirs
are used for using custom tools in custom build steps (passing paths to where you have you build tools), not to where CC, CXX, etc. I'd like @starkos or @samsinsane to confirm my guess though.
Then shouldn't the $(EXE_PATHS)
bit be missing from the build rules involving $(CXX)
? Ultimately, the issue here is the inconsistency in path handling between the compile and link steps.
Good catch. I'll investigate further and get back to you.
BTW, https://premake.github.io/docs/bindirs/ has no real documentation.
BTW, https://premake.github.io/docs/bindirs/ has no real documentation.
Yup, that's a definite issue. I think it's lead to some of my confusion as well.
@nickclark2016 That is correct, bindirs
was intended for the custom build rules system. The new gmake2
action built C++ support around the rules
system, which has created this weird scenario of bindirs
impacting regular project compilation.
@complexmath for GCC there is gccprefix
which might work for your situation? It won't replicate PATH=<path>:$PATH
but it might otherwise do what you're expecting? Alternatively, you could look into using makesettings
to configure the paths as you expect? This will inject whatever Makefile settings you want just after the EXE_PATHS
output but before the pre-build commands output.
what if there's more than 1 version of the same compiler installed?
does bindirs
allow choosing one over the other?