I'm trying to compile a simple hello world program:
main.cpp
#include <iostream>
#include <test/t.hpp>
int main( int argc , char** args )
{
std::cout << test() << std::endl;
int x;
std::cin >> x;
return 0;
}
test/t.hpp
#ifndef TEST_T_HPP_INCLUDED
#define TEST_T_HPP_INCLUDED
int test();
#endif // TEST_T_HPP_INCLUDED
test/t.cpp
#include <test/t.hpp>
int test()
{
return 42;
}
With this makefile:
executable_name = testapp
cpp_compiler = g++
cpp_compiler_flags += -std=c++14
cpp_compiler_flags += -g
cpp_linker_flags += -g
linked_libraries +=
included_directories += -I./src/
source_dir = src
source_files += main.cpp
source_files += test/t.cpp
object_dir = obj
object_files = $(addprefix $(object_dir)/,$(source_files:=.o))
directories = $(sort $(foreach i,$(object_files),$(dir $i)))
source_files := $(addprefix $(source_dir)/,$(source_files))
all: make_directories tool
tool: $(object_files)
$(cpp_compiler) $(cpp_linker_flags) -o $(executable_name) $(object_files) $(linked_libraries)
$(object_files): $(source_files)
$(cpp_compiler) $^ $(cpp_compiler_flags) $(included_directories) -o $@
make_directories:
@sh -c \
'for d in $(directories); do \
if [ ! -d $$d ]; \
then echo mkdir -p $$d; mkdir -p $$d; \
fi \
done'
By using the TDM-GCC-4.8.1 tools coming with CodeBlocks 13.12 (and mingw32-make)
But I get over 10000 errors like this:
obj/src/main.cpp.o:crtend.c:(.text+0x26a80): first defined here
obj/src/test/t.cpp.o:crtend.c:(.text+0x26880): multiple definition of `std::__us
e_cache<std::__numpunct_cache<char> >::operator()(std::locale const&) const'
obj/src/main.cpp.o:crtend.c:(.text+0x26880): first defined here
obj/src/test/t.cpp.o:crtend.c:(.text+0x350d0): multiple definition of `std::ostr
eambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambu
f_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostrea
mbuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double
) const'
obj/src/main.cpp.o:crtend.c:(.text+0x350d0): first defined here
obj/src/test/t.cpp.o:crtend.c:(.text+0x35ee0): multiple definition of `std::num_
put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std:
:ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, doubl
e) const'
obj/src/main.cpp.o:crtend.c:(.text+0x35ee0): first defined here
I guess those are linker errors, as I can see for a splitsecond the source files to get compiled.
What did I miss here?
EDIT
this rule made it work:
$(object_files): $(object_dir)/%.o : $(source_dir)/%
$(cpp_compiler) -c $^ $(cpp_compiler_flags) $(included_directories) -o $@
The problem is here:
This recipe makes all source files prerequisites of every object file. So when Make tries to build
main.o, it executesEverything goes into
main.o, and everything goes intot.o, so when the linker tries to link the object files together, it hits multiple definitions everywhere.Try a static pattern rule:
EDIT:
P.S. you might have to help Make find
t.cpp: