I generated a makefile out of a codeblocks project (written in c++11), so I can use Atom as IDE. But it does not update the object files when I i.e. change the default constructors parameter in the header file, which is really annoying. It just links the existing object files again. But even if I make a little change to the .cpp file, it recompiles the object without recognizing the changes in the header file. The only quick fix I found is to delete the object file manually, so it really generates it completely new. The header part I currently often change looks like this:
VRParticles(): VRParticles(123){}
The whole makefile is available here (generated using cbp2make): https://github.com/Pfeil/polyvr/blob/master/Makefile
(Please note that I am just a fairly new contributor and not responsible for the way this is programmed ;) )
I use the makefile mostly with one of those two commands:
make -j 3 build_debug
make debug
Note that everything compiles fine when I delete VRParticles.o or do make clean and make debug.
Please note that my experience with makefiles is very low. The makefile basically works like this (remember the link to the full version above):
OBJ_DEBUG = # all object files
build_debug: before_debug out_debug after_debug
debug: before_build build_debug after_build
out_debug: before_debug $(OBJ_DEBUG) $(DEP_DEBUG)
$(LD) $(LIBDIR_DEBUG) -o $(OUT_DEBUG) $(OBJ_DEBUG) $(LDFLAGS_DEBUG) $(LIB_DEBUG)
$(OBJDIR_DEBUG)/src/addons/Bullet/Particles/VRParticles.o: src/addons/Bullet/Particles/VRParticles.cpp
$(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/addons/Bullet/Particles/VRParticles.cpp -o $(OBJDIR_DEBUG)/src/addons/Bullet/Particles/VRParticles.o
I'd really like give more information, but I have no idea what else could be important, so please ask if you need more. My question basically is how I need to modify the makefile (I guess this file contains the issue) so the object files get updated if needed. Without recompiling everything.
I'm on Linux (Ubuntu 14.04 LTS).
If we look at your dependencies for VRParticles.o:
VRParticles.o : src/addons/Bullet/Particles/VRParticles.cpp
You are telling make that the object file only depends on VRParticles.cpp. So when you update VRParticles.h, that doesn't matter - you never listed VRParticles.h as a dependency! Thankfully, gcc can generate those dependencies for you automatically:
$(CC) $(other flag stuff) -MP -MMD -MF $(#:.o=.d) -o $# -c $<
That will create a file VRParticles.d which will have make-style rules for dependencies, in this case something like:
VRParticles.o : VRParticles.d
So at that point, all we need is to include them:
DEPENDENCY_FILES = $(....)
-include $(DEPENDENCY_FILES)
Related
I want to type the following:
make fileName.cpp
To compile, and then to execute:
./fileName
If I have a make file like this:
commandToCompileFileName:
g++ -o fileName fileName.cpp
Then I can do:
make commandToCompileFileName
And then:
./fileName
I want to be able to do this with different files, without having to write a different prompt for each of them in makefile. So something would be in place of
commandToCompileFileName
in the makefile that would just compile whatever I type in after make, and the executable would just be named the same minus the .cpp.
This page in the very first paragraph describes precisely what I want and probably answers my question, yet I couldn't figure it out after playing around with '$#' and '$<'.
You actually do not need a Makefile to do this: make ships with a whole bunch of default rules, one of which creates programs from .cpp files.
In other words, just type make fileName, and be happy :)
(if you want to custom compilation flags, see the CXXFLAGS and LDFLAGS variables)
I use the following:
run_% : %
#echo "---- running $< ----"
$<
.PHONY : run_%
So that when you do, for example, make run_test it builds test target and runs it.
What I'm trying to do is create a c++ file from an object file but I cannot figure out a way to do so.
INCLUDEDIR = ../headers
CXXFLAGS = -std=c++11 -I $(INCLUDEDIR) -Wall -Wfatal-errors -O2
all:primeFactors.o
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
g++ $(CXXFLAGS) -c $< -o $#
When I try to build this I get
make: *** No rule to make target 'primeFactors.cpp', needed by
'primeFactors.o'. Stop.
which I understand but when I take out the primeFactor.cpp argument I then get told there is nothing to be done with the make file. So is there a way to do this?
In general; no, you cannot do that. An object file (.o file) is the result of the code passing through the compiler front-end (to parse the language) the optimizer (to make it run fast) and the compiler back-end (to produce code that will run on your CPU).
This process is not reversible. You cannot go from compiled code back to source.
can you create a c++ file from an .o object file with makefile?
A makefile will allow you to do that only if you have an underlying tool to do it. make, which uses makefiles to do its job, does not have any built-in mechanisms to pull that off.
Your makefile has a rule for building primeFactors.o.
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
It says that primeFactors.cpp and $(INCLUDEDIR)/primeFactors.h are needed to build primeFactors.o. If you don't have those files, or no rules to build them, there is no way for make to build primeFactors.o.
How this simple make script knows that some of cpp files is changed? Does it means that for each .o file it will look for corresponding .cpp one? What if extension will be different - for example .c
hellomake: hellomake.o hellofunc.o
gcc -o hellomake hellomake.o hellofunc.o -I.
UPD:
According to my understanding scrip I provide should not look to c and cpp files. And when I asked to build project second time MAKE told me "make: 'hellomake' is up to date.
But I was surprised when I have changed hellomake.cpp MAKE has decided do rebuild project. Why?
GNU make has many builtin rules. Run make -p to find them. And use the existing rules in your Makefile, see this or that or this
Obvious documentation links were already provided. I just wanted to comment on your example. You told make the following:
The file hellomake relies on hellomake.o and hellofunc.o, ie. both are prerequisites of hellomake. If any prerequisite changes since the last build, hellomake will be rebuilt. How (re-) building is done is the second line, ie. the gcc invocation.
To answer your question: The snippet provided, will not look for any cpp files. You need different rules in addition for that, ie. something like
%.o: %.cpp
gcc -I. -c #< -o $#
In case you are searching for a rather generic Makefile to start with, I'd recommend this one. It has been the basis for many of my Makefiles in use.
I'm setting up Autotools for a large scientific code written primarily in C++, but also some CUDA. I've found an example for compiling & linking CUDA code to C code within Autotools, but I cannot duplicate that success with C++ code. I've heard that this is much easier with CMake, but we're committed to Autotools, unfortunately.
In our old hand-written Makefile, we simply use a make rule to compile 'cuda_kernels.cu' into 'cuda_kernels.o' using nvcc, and add cuda_kernels.o to the list of objects to be compiled into the final binary. Nice, simple, and it works.
The basic strategy with Autotools, on the other hand, seems to be to use Libtool to compile the .cu files into a 'libcudafiles.la', and then link the rest of the code against that library. However, this fails upon linking, with a whole bunch of "undefined reference to ..." statements coming from the linker. This seems like it might be a name-mangling issue with g++ vs. the nvcc compiler (which would explain why it works with C code), but I'm not sure what to do at this point.
All .cpp and .cu files are in the top/src directory, and all the compilation is done in the top/obj directory. Here's the relevant details of obj/Makefile.am:
cuda_kernals.cu.o:
$(NVCC) -gencode=arch=compute_20,code=sm_20 -o $# -c $<
libcudafiles_la_LINK= $(LIBTOOL) --mode=link $(CXX) -o $# $(CUDA_LDFLAGS) $(CUDA_LIBS)
noinst_LTLIBRARIES = libcudafiles.la
libcudafiles_la_SOURCES = ../src/cuda_kernels.cu
___bin_main_LDADD += libcudafiles.la
___bin_main_LDFLAGS += -static
For reference, the example which I managed to get working on our GPU cluster is available at clusterchimps.org.
Any help is appreciated!
libtool in conjunction with automake currently generates foo.lo (libtool-object metadata) files, the non-PIC (static) object foo.o, and the PIC object .libs/foo.o.
For consistent .lo files, I'd use a rule like:
.cu.lo:
$(LIBTOOL) --tag=CC --mode=compile $(NVCC) [options...] -c $<
I have no idea if, or how, -PIC flags are handled by nvcc. More options here. I don't know what calls you are making from the program, but are you forward declaring CUDA code with C linkage? e.g.,
extern "C" void cudamain (....);
It seems others have run up against the libtool problem. At worst, you might need a 'script' solution that mimics the .lo syntax and file locations, as described on the clusterchimps site.
I am trying to compile my project which has the following structure
Project:
MakeFile
Executable
Source1
.cxx
.h
Source2
.cxx
.h
Build
*.o
And I'm having difficulty writting a Makefile to compile. I currently have commands like:
Src1 = $(wildcard $(SRCDIR1)/*.cxx)
Obj1 = $(patsubst $(SRCDIR1)/%.cxx, $(OBJDIR)/%.o, $(Src1))
But then I have difficulty making the compile rules for the object files a) Because I can no longer do:
$(Obj1): %.cxx
$(CXX) $(CFLAGS) -c $(#:.o=.cxx) -o $#
Because the '$#' command now includes the path of the build directory and b) because the prerequisites now include the build path and I should have a source path. I have read large bits of the make manual to try and find a solution but no luck.
Any help towards a solution appreciated!
Jack
From personal experience, after playing around a bit with "raw" Makefiles, I'd really recommend using some tool building the Makefiles for you, like automake or cmake.
You'll still have to specify all the source files manually - but at least I prefer that to manually fiddling around with the Makefiles.
One option I prefer is building an isomorphic directory structure in the build directory. That is, a source file ${src_dir}/project_x/main.cxx builds into ${build_dir}/project_x/main.o. This way you are protected from name clashes when there are source files with the same name in different source directories. The compiler rule would look something like:
${obj_dir}/%.o : ${src_dir}/%.cxx # % includes directory name, e.g. project_x/main
#-mkdir -p ${#D}
${CXX} -c -o $# ${CPPFLAGS} ${CXXFLAGS} $<
Notice how in the above it creates the target directory on the fly. This is a bit simplistic, in a real-world build system object files depend (using order-only dependency) on its directory, so that make automatically creates the destination directory if it does not exist instead of speculatively trying to create them for each target object file even if it already exists.