clion makefile "No Compilation commands found"
I am using clion-2021.3.3 in a standalone environment using Makefiles.
I have created a project using https://www.jetbrains.com/help/clion/makefiles-support.html#load-makefile-project but get hung up on step 5.
because "Analyzing Makefile" says "No Complication commands found".
I can build build the project from the Clion IDE.
But Clion has not built project information to support things like going to the Declaration of a function -- it takes me to the namespace when I expect it to take me to the Class definition.
Expected hanging over basic::Ls::Shutdown() would show me that it is in the basic::Ls class and that it was declared in Ls.hh
My Makefile defines variables;
- IncludeDirs
- CppOptions
- LinkOptions
- Libraries
- Execs
- Packages
And then includes this general Makefile given below.
The project structure is:
bin/{Execs*}
include/{Packages*}
src/{Packages*}
Is there way to make Clion 2021.3.3 properly parse the Makefile including this general Makefile include?
#---------------------------------------------------------------------------
# (C) 1999 - 2004 Jacob Dreyer - Geotechnical Software Services
# jacob.dreyer@geosoft.no - http://geosoft.no
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#
# GnuMake crash course:
#
# target : depends
# rule
#
# target - the parameter given to make. I.e. what to build
# depends - file or other targets target depends on
# rule - how to create target (note that rule is preceeded by a TAB char)
# $(VAR) - environment variable or variable defined above
# $@ - Current target
# $* - Current target without extension
# $< - Current dependency
#
#---------------------------------------------------------------------------
# May 2012: Reveived massive updates to eliminate circular dependencies,
# and to make specific portions of this makefile completely specific
# to the level of the make (Toplevel/Sub(source))
#
#---------------------------------------------------------------------------
#
# Directories
#
# Common to all makes (Primary and Sub)
#---------------------------------------------------------------------------
SourceDir = $(DEV_ROOT)/src
TargetDir = $(DEV_ROOT)/obj
LibDir = $(DEV_ROOT)/lib
MakeDir = $(DEV_ROOT)/make
BinDir = $(DEV_ROOT)/bin
DocsDir = $(DEV_ROOT)/docs
CurrentDir = $(CURDIR)
#
# The following small snippet is specific to Sub-Make processing only.
# We need to make sure that some variables are defined correctly before
# the other expansions. This will allow for the Sub-Make speficic operations
# to match correctly based on the existing rules defined for all levels
# of makes.
#
# Note: Source being defined is the same as being a SubMake
ifdef Source
ifdef Main
PackageSourceDir = $(CurrentDir)
PackageTargetDir = $(TargetDir)/$(subst $(SourceDir)/,,$(CurrentDir))
Executable = $(BinDir)/$(Main)
else
Packages = $(subst $(SourceDir)/,,$(CurrentDir))
PackageSourceDir = $(SourceDir)/$(Packages)
PackageTargetDir = $(TargetDir)/$(Packages)
endif
CurrentPackage = $(subst $(SourceDir)/,,$(CurrentDir))
JavaMainClass = $(subst /,.,$(Packages)).$(Main)
endif
#
# End of SubMake specific section.
#
PackageList = $(Packages) $(JavaPackages)
PackageTargetDirs = $(patsubst %,$(TargetDir)/%,$(Packages))
JRE = $(JAVA_HOME)/jre/lib/rt.jar
#
# Miscellaneous variables that are global in nature. Not specific to
# sub-makes only.
#
ClassPath = $(JRE)$(X)$(TargetDir)$(X)$(ThirdPartyJars)
JavaPackageNames = $(subst /,.,$(JavaPackages))
IncludePath = -I$(SourceDir) $(IncludeDirs:%=-I%)
LibNames = $(subst /,,$(Packages))
LibDirs = -L$(LibDir) $(LibraryDirs:%=-L%)
LibList = $(LibNames:%=-l%) $(Libraries:%=-l%)
LinkLibs = $(LibNames:%=-l%)
PkgLibraries = $(patsubst %,$(LibDir)/lib%.a,$(LibNames))
Executables = $(patsubst %,$(BinDir)/%,$(Execs))
ifdef IS_UNIX
X = :
else
X = \;
endif
#---------------------------------------------------------------------------
#
# Tools & Options
#
# Tools and options are not make level specific. They are globally
# defined such that all levels of the make process may have access to
# their definition.
#---------------------------------------------------------------------------
Print = @echo
Copy = cp
CCompiler = gcc
CppCompiler = g++
Linker = g++
#MakeDepend = makedepend
MakeDepend = gcc -M
MakeDir = mkdir -p
Delete = rm -fr
StaticArchiver = ar
DynamicArchiver = gcc
FortranCompiler = f77
JavaCompiler = $(JAVA_HOME)/bin/javac
JavaArchiver = $(JAVA_HOME)/bin/jar
JarSigner = $(JAVA_HOME)/bin/jarsigner
JavadocGenerator = $(JAVA_HOME)/bin/javadoc
JniCompiler = $(JAVA_HOME)/bin/javah
RmiCompiler = $(JAVA_HOME)/bin/rmic
JavaExecute = $(JAVA_HOME)/bin/java
Purify = purify
WordCount = wc
List = cat
Silent =
#MakeOptions = -k -s
MakeDependOptions =
StaticArchiverOptions = rc
DynamicArchiverOptions = -shared
JavaArchiverOptions =
JniOptions =
RmiOptions = -d $(TargetDir) -classpath $(ClassPath)
FortranOptions =
JavaCompilerOptions = -d $(TargetDir) -classpath $(ClassPath) \
-sourcepath $(SourceDir) -deprecation
JavaRunOptions = -classpath $(ClassPath)
PurifyOptions =
JavadocOptions = -d $(DocsDir) \
-sourcepath $(SourceDir) \
-classpath $(ClassPath) \
-author \
-package \
-use \
-splitIndex \
-version \
-link file:$(JAVA_HOME)/docs/api \
-windowtitle $(JavadocWindowTitle) \
-doctitle $(JavadocDocTitle) \
-header $(JavadocHeader) \
-bottom $(JavadocFooter)
WordCountOptions = --lines
Empty =
Space = $(Empty) $(Empty)
DependFilesExist = $(shell ls $(DepFiles) 2>/dev/null)
# **************************************************************************
# Define an array of libnames tied to the actual package defined in the
# $(Packages) variable. This will give a resolution of an expansion of
# an individual package name to its corresponding library name.
# For instance for Packages = dds:
# dds := $(LibDir)/libdds.a
#
# Later the target for the library $(dds): will be defined, and when
# expanded the library will be an actual dependency later for the
# executable.
# **************************************************************************
#define BuildLibVars
#$(1) = $(addprefix $(LibDir)/,$(patsubst %,lib%.a,$(subst /,,$(1))))
#endef
#$(foreach pkg,$(Packages),$(eval $(call BuildLibVars,$(pkg))))
#---------------------------------------------------------------------------
#
# Rules for building the project. All Sub-Make specific rules should be
# found in the Sub-Make section (found below).
#
#---------------------------------------------------------------------------
ifdef Source
.DEFAULT_GOAL := package
else
.DEFAULT_GOAL := all
endif
# --------------------------------------------------------------------------
#
# Where the above were rules for building the actual source files, this
# is a list of targets that will be used to build the end product.
#
# --------------------------------------------------------------------------
# Create target directory for each Package
# This causes a target to be defined for each Package defined in the toplevel
# Makefile. All packages (whitespace delimited) will create a target directory
# within the $(TargetDir) directory.
define MkTgtDirs
$(1):
@$(MakeDir) -p $(1)
endef
$(foreach dir,$(PackageTargetDirs),$(eval $(call MkTgtDirs,$(dir))))
# Create a target for each Package defined in the toplevel Makefile.
# Each package will depend on it's output directory being created (above
# set of target definitions). After that it will cd to the packages source
# directory and build the package itself (composing of depends, objects, and
# any library output).
define PkgTarget
$(1): $(patsubst %,$(TargetDir)/%,$(1))
@$(Print) "Building package : [$(1)]"
@cd $(SourceDir)/$(1) && ${MAKE} -j 4 package
endef
$(foreach pkg,$(Packages),$(eval $(call PkgTarget,$(pkg))))
#
# This defines a target for each and every executable defined in
# Execs. It will CD into the directory where the exec resides, and
# perform the compile and link for the executable.
#
define EXECS
$(BinDir)/$(1) : $(Packages)
@cd $(SourceDir)/$(1) && ${MAKE} link_$(1)
@$(Print) "Executable[ $(1) ] built successfully."
endef
$(foreach exec,$(Execs),$(eval $(call EXECS,$(exec))))
#
# This defines a set of "Pure" targets for the Execs specified in the
# top level makefile. In the case of netct, the user can make netct,
# make bin/netct or make by itself to accomplish the same task.
#
define Pure_EXECS
$(1): $(BinDir)/$(1)
endef
$(foreach exec,$(Execs),$(eval $(call Pure_EXECS,$(exec))))
# all: This is the default target and will build any and all executables
# defined within the $(Executables) variable expansion.
.PHONY : all
all : $(Executables)
@$(Print) "Target $@ completed successfully."
# help: This target will print out information about the miscellaneous
# targets available for building in the tree.
.PHONY : help
help:
$(Print)
$(Print) "Available Targets"
$(Print) "-----------------"
ifndef Source
$(Print) "all [default] - Build all executables and sources in the tree"
$(Print) "clean - Remove all object files, libraries, and"
$(Print) " executables in the tree."
$(Print)
$(Print) "Packages/Libraries available to be built:"
$(Print) $(foreach pkg,$(Packages),"$(pkg), ")
$(Print)
$(Print) "Executables available to be built:"
$(Print) $(foreach ex,$(Execs) $(Executables), "$(ex), ")
$(Print)
$(Print)
else
$(Print) "package [default] - Build all objects, and the associated"
$(Print) " library for the package. If the package"
$(Print) " is an executable, the executable is"
$(Print) " built and relinked."
$(Print) "clean - Remove all object files and libraries"
$(Print) " for the package."
$(Print) "objects - Build the object files for the package"
endif
# make clean
.PHONY : clean
clean :
@$(Print) "Cleaning in $(Packages) $(Execs) ..."
@$(foreach dir,$(Packages) $(Execs),cd $(SourceDir)/$(dir) && \
${MAKE} -j 4 cleanup;)
@$(Print) Done clean.
jar : $(JarFile)
jarsign : $(JarFile)
@$(JarSigner) -keystore GeoSoftKeystore $(JarFile) myself
# make statistics
#_statisticsall :
# @$(Print) $(SourceFiles) >> $(DEV_ROOT)/files.tmp
#statistics :
# @$(List) $(DEV_ROOT)/files.tmp | xargs $(WordCount) $(WordCountOptions)
# @$(Delete) $(DEV_ROOT)/files.tmp
# $(Print) Done statistics.
# make pure
#$(Executable).pure :
# $(Purify) $(PurifyOptions) $(CppCompiler) $(LinkOptions) $(LibDirs) \
# $(LibList) $(ObjectFiles) -o $@
#pure : $(Executable).pure
# Execute
#_runexe :
# $(Executable) $(RunParameters)
#_runjava :
# $(JavaExecute) $(JavaRunOptions) $(JavaMainClass) $(RunParameters)
#run : _runjava
#---------------------------------------------------------------------------
#
# Classification of files
#
# Specific to sub-makes only. No source files should exist in the
# toplevel.
#---------------------------------------------------------------------------
# This checks to see if we are at a submake level. If not then the next
# section (up until the endif) is skipped. Otherwise when making
# libraries from source trees, the sub-make process will be invoked.
#
# Note: Source being defined equates to a Sub-Make. Source is defined in the
# package directory makefiles.
ifdef Source
# Source Matching based on type of file.
JavaFiles = $(filter %.java, $(Source))
CcFiles = $(filter %.cc, $(Source))
CppFiles = $(filter %.cpp, $(Source))
CFiles = $(filter %.c, $(Source))
FortranFiles = $(filter %.f, $(Source))
CorbaFiles = $(filter %.idl, $(Source))
OtherSourceFiles = $(filter-out $(JavaFiles) $(CppFiles) $(CcFiles) \
$(CFiles) \
$(FortranFiles) $(CorbaFiles), \
$(Source))
ManifestFile = $(PackageSourceDir)/Manifest
SourceFiles = $(JavaFiles:%.java= $(PackageSourceDir)/%.java)\
$(CcFiles:%.cc= $(PackageSourceDir)/%.cc)\
$(CppFiles:%.cpp= $(PackageSourceDir)/%.cpp)\
$(CFiles:%.c= $(PackageSourceDir)/%.c)\
$(FortranFiles:%.f= $(PackageSourceDir)/%.f)
DepFiles = $(JavaFiles:%.java= $(PackageSourceDir)/%.d)\
$(CcFiles:%.cc= $(PackageSourceDir)/%.d)\
$(CppFiles:%.cpp= $(PackageSourceDir)/%.d)\
$(CFiles:%.c= $(PackageSourceDir)/%.d)\
$(FortranFiles:%.f= $(PackageSourceDir)/%.d)
# Target Conversion: Convert files to their destined output names and store
# them in associated variable names.
JavaClassFiles = $(JavaFiles:%.java= $(PackageTargetDir)/%.class)
JavaClassFilesRel = $(JavaFiles:%.java= $(Package)/%.class)
RmiStubFiles = $(RmiSource:%.java= $(PackageTargetDir)/%_Stub.class)
RmiSkeletonFiles = $(RmiSource:%.java= $(PackageTargetDir)/%_Skel.class)
JniClassFiles = $(JniSource:%.java= $(PackageTargetDir)/%.class)
JniHeaders = $(JniSource:%.java= $(PackageSourceDir)/%.h)
ObjectFiles = $(CFiles:%.c= $(PackageTargetDir)/%.o)\
$(CcFiles:%.cc= $(PackageTargetDir)/%.o)\
$(CppFiles:%.cpp= $(PackageTargetDir)/%.o)\
$(FortranFiles:%.f= $(PackageTargetDir)/%.o)
OtherTargetFiles = $(OtherSourceFiles:%=$(PackageTargetDir)/%)
ThirdPartyJarsTmp = $(patsubst %,$(LibDir)/%,$(JavaLibraries))
ThirdPartyJars = $(subst $(Space),$(X),$(ThirdPartyJarsTmp))
# This will define The Java Package name (based on $(Package)) if there
# are any existing java source files within the current level of make.
# It will also assign the name of the JarFile based on the name of the
# package.
ifneq "$(words $(JavaFiles))" "0"
JavaPackageName = $(subst /,.,$(Package))
JarFile = $(LibDir)/$(subst /,,$(Package)).jar
endif
# This will define the name of the library based on whether or not any
# normal C,C++, etc files are found in the current level of make. If so
# then the name of the library depends on the $(Package) variable as well.
ifneq "$(words $(ObjectFiles))" "0"
StaticLibrary = $(LibDir)/lib$(subst /,,$(Package)).a
endif
# ----------------------------------------------------------------------------
#
# Sub-Make rules:
#
# These rules are specific to building source files into objects that will
# be assembled into libraries. These are at the sub-make level only as
# the top level of any project should not have source files within it.
#
# ----------------------------------------------------------------------------
# .c -> .o
$(PackageTargetDir)/%.o : $(PackageSourceDir)/%.c
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(CCompiler) $(COptions) -c $(IncludePath) $< -o $@
%.o : $(PackageSourceDir)/%.c
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .cc -> .o
$(PackageTargetDir)/%.o : $(PackageSourceDir)/%.cc
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(CppCompiler) $(CppOptions) -c $(IncludePath) $< -o $@
%.o : $(PackageSourceDir)/%.cc
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .cpp -> .o
$(PackageTargetDir)/%.o : $(PackageSourceDir)/%.cpp
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(CppCompiler) $(CppOptions) -c $(IncludePath) $< -o $@
%.o : $(PackageSourceDir)/%.cpp
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .cc -> .d
$(PackageSourceDir)/%.d : $(PackageSourceDir)/%.cc
@$(Print) "[$(CurrentPackage)]: Building dependency for $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(SHELL) -ec '$(CppCompiler) -M -MT $(PackageTargetDir)/$*.o \
$(CppOptions) $(IncludePath) $< -o $@'
%.d : $(PackageSourceDir)/%.cc
@$(Print) "[$(CurrentPackage)]: Building dependency for $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(SHELL) -ec '$(CppCompiler) -M -MT $(PackageTargetDir)/$*.o \
$(CppOptions) $(IncludePath) $< -o $@'
# .cpp -> .d
$(PackageSourceDir)/%.d : $(PackageSourceDir)/%.cpp
@$(Print) "[$(CurrentPackage)]: Building dependency for $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(SHELL) -ec '$(CppCompiler) -M -MT $(PackageTargetDir)/$*.o \
$(CppOptions) $(IncludePath) $< -o $@'
%.d : $(PackageSourceDir)/%.cpp
@$(Print) "[$(CurrentPackage)]: Building dependency for $@ from $<"
@$(MakeDir) $(dir $@)
$(Silent)$(SHELL) -ec '$(CppCompiler) -M -MT $(PackageTargetDir)/$*.o \
$(CppOptions) $(IncludePath) $< -o $@'
%.o : $(PackageSourceDir)/%.cpp
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .f -> .o
$(PackageTargetDir)/%.o : $(PackageSourceDir)/%.f
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(FortranCompiler) $(FortranOptions) -c $< -o $@
%.o : $(PackageSourceDir)/%.f
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
$(Silent)$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .java -> .class
$(PackageTargetDir)/%.class : $(PackageSourceDir)/%.java
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(JavaCompiler) $(JavaCompilerOptions) $<
%.class : $(PackageSourceDir)/%.java
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .class -> .h
$(PackageSourceDir)/%.h : $(PackageTargetDir)/%.class
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(JniCompiler) $(JniOptions) $(JavaPackageName).$*
%.h : %.class
@$(Print) "[$(CurrentPackage)]: Building $@ from $<"
@$(MAKE) $(MakeOptions) $(PackageSourceDir)/$@
# .o -> .a
#%.a : $(ObjectFiles)
$(LibDir)/%.a: $(ObjectFiles)
@$(Print) "[$(CurrentPackage)]: Creating library: $@"
@$(StaticArchiver) -r $@ $(ObjectFiles)
%.a : $(ObjectFiles)
@$(Print) "[$(CurrentPackage)]: Creating library: $@"
@$(StaticArchiver) -r $(LibDir)/$@ $(ObjectFiles)
# .o -> .so
%.so : $(ObjectFiles)
@$(Print) "[$(CurrentPackage)]: Creating shared library: $@"
@$(DynamicArchiver) $(ObjectFiles) $(DynamicArchiverOptions) \
-o $(LibDir)/$@
$(LibDir)/%.so : $(ObjectFiles)
@$(Print) "[$(CurrentPackage)]: Creating shared library: $@"
@$(DynamicArchiver) $(ObjectFiles) $(DynamicArchiverOptions) -o $@
# .class -> .jar
%.jar : @$(JavaClassFiles) $(OtherTargetFiles)
@$(Print) "[$(CurrentPackage)]: Creating jar: $@"
@cd $(TargetDir); $(JavaArchiver) -cf $(LibDir)/$@ \
@$(JavaClassFilesRel) $(OtherTargetFiles)
# .class -> JavaDoc
javadoc :
@$(Print) $(JavaPackageNames) > $(DEV_ROOT)/packages.tmp
@$(JavadocGenerator) $(JavadocOptions) @$(DEV_ROOT)/packages.tmp
@$(Delete) $(DEV_ROOT)/packages.tmp
@$(Print) Done JavaDoc.
# .class -> _Stub.class
$(PackageTargetDir)/%_Stub.class : $(PackageTargetDir)/%.class
@$(Print) "[$(CurrentPackage)]: Compiling stub $@ from $<"
@$(RmiCompiler) $(RmiOptions) $(JavaPackageName).$*
%_Stub.class : %.class
@$(Print) "[$(CurrentPackage)]: Compiling stub $@ from $<"
@$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# .class -> _Skel.class
$(PackageTargetDir)/%_Skel.class : $(PackageTargetDir)/%.class
@$(Print) "[$(CurrentPackage)]: Compiling skel $@ from $<"
@$(RmiCompiler) $(RmiOptions) $(JavaPackageName).$*
%_Skel.class : %.class
@$(Print) "[$(CurrentPackage)]: Compiling skel $@ from $<"
@$(MAKE) $(MakeOptions) $(PackageTargetDir)/$@
# *************************************************************************
#
# Targets for Sub-Make builds.
#
# *************************************************************************
.PHONY : cleanup
cleanup :
@$(Delete) $(DepFiles)
@$(Delete) $(PkgLibraries)
@$(Delete) $(ObjectFiles)
# @$(Delete) $(LocalTmpFiles)
# for now, don't delete LocalTmpFiles
define LinkExec
.PHONY : link_$(1)
link_$(1) : $(ObjectFiles)
@$(Print) "Linking $(Executable)"
$(Silent)$(Linker) $(LinkOptions) -o $(Executable) $(LibDirs) $(ObjectFiles) $(LibList)
@$(Print) "Complete."
endef
$(foreach exec,$(Execs),$(eval $(call LinkExec,$(exec))))
.PHONY : MakePackageDepends
MakePackageDepends : $(DepFiles)
@$(Print) "Makedepend complete."
# End of Sub-Make specific items.
endif
.PHONY : objects
#objects: $(DepFiles) $(ObjectFiles)
objects: $(LocalTmpFiles) $(DepFiles) $(ObjectFiles)
@$(Print) "[$(CurrentPackage)]: objects built successfully."
.PHONY : library
ifndef Main
library: objects $(PkgLibraries)
@$(Print) "$(PkgLibraries) Built successfully."
.PHONY : package
package: library
@$(Print) "Make package $(Packages) complete."
else
.PHONY : package
package: link_$(CurrentPackage)
endif
#-include $(DependencyFile)
ifeq ($(DependFilesExist),$(DepFiles))
-include $(DepFiles)
endif
Please sign in to leave a comment.
Hello, has anyone found a solution to this getting the same error
Hi Scott Harris and Brymher!
Please send your projects to clion-support at jetbrains.com, we will need them to investigate the issues you faced. Thanks!