Unfortunately I cannot post all of the source code here. I can describe the structure though. All header files have #ifndef/#define/#endif guards. The structure is as follows:
node.h - included by tree.h
tree.h - included by tree.cpp and main.cpp
tree.cpp
main.cpp
In node.h in the global namespace, I declare the following free standing function:
bool char_sort_func(Path first, Path second)
{
return (first->label() < second->label());
}
(Note: as shown bellow, a Path is just a shared_ptr) When I try to build, I get a multiple definition error saying that the function is present in both tree.o and main.o:
> make
g++ -c -g -Wall main.cpp -I /usr/include
g++ -c -g -Wall tree.cpp -I /usr/include
g++ -Wall -o tool tree.o main.o -L /usr/lib -l boost_program_options
main.o: In function `char_sort_func(boost::shared_ptr<Edge>, boost::shared_ptr<Edge>)':
node.h:70: multiple definition of `char_sort_func(boost::shared_ptr<Edge>, boost::shared_ptr<Edge>)'
tree.o:node.h:70: first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1
I tried searching all of the source files to see if that was true, however, I don't see it in any wrong places:
> grep char_sort_func *
Binary file main.o matches
node.h:bool char_sort_func(Path first, Path second)
node.h: std::sort(edges_.begin(), edges_.end(), char_sort_func);
Binary file trie.o matches
Sure enough though, it is in the binary files. How can I restructure my code to prevent this linking issue?
This will happen if you declare normal functions in a .h file, because they will be generated in every file that #includes it. Perhaps you meant to declare it inline or static?
Related
I can compile my executable file by follow commands
g++ -c main.cpp
g++ main.o -o my_exe -lmy
I do not need to specify the path of the libmy.a using -L path during link.
The libmy.a can automatically find by system.
Now I want to find the path of libmy.a but I have no idea where it is.
How can I obtain the full path of libmy.a?
Instead of:-
g++ main.o -o my_exe -lmy
link your program with:-
g++ main.o -o my_exe -lmy -Wl,-trace
This will make g++ pass the diagnostic option -trace to the linker. The linker
will print the pathname by which it locates every object file, shared library or static libary that it inputs. Inspect the output and you will find the full pathname of libmy.a
I'm trying to build a precompiled header and an executable, like so:
g++ -g -Wall -std=c++17 \
-c ./src/pch.hpp -o ./build/pch.hpp.gch
g++ -g -Wall -std=c++17 \
-c ./src/*.cpp \
-I./build/ -include pch.hpp
The pch.hpp.gch file is created correctly. But for each of the .cpp files, I'm getting the following error:
1 error generated.
<built-in>:1:10: fatal error: 'pch.hpp' file not found
#include "pch.hpp"
I think my compilation line is correct, based on the gcc Precompiled Headers documentation:
-I./build/ tells it to add build directory to the include search-path.
-include pch.hpp prepends an #include <pch.hpp> directive to each file.
The compiler searches for precompiled headers, with the .gch suffix, for each of its #include directives.
Why is my compilation line not working as expected?
There are some things I've tried which do give me better results, but they don't look correct to me.
If I modify the include to search for a .gch file, then the file is found, in line with what I'd expect. That is, -include pch.hpp.gch, instead of -include pch.hpp .
But then, the PCH is interpreted as a binary file, and compilation fails:
g++ -g -Wall -std=c++17 \
-c ./src/*.cpp \
-I./build/ -include pch.hpp.gch
./build/pch.hpp.gch:2:22: error: source file is not valid UTF-8
I'm not surprised that #include <pch.hpp.gch> doesn't compile. But I'm mentioning this since it seems to show that in my original command, the build folder is searched (as I expected), but the mechanism that knows to use the .gch file instead of a regular header isn't active. Weird.
Alternatively, if I add the src folder to the header search path, it works:
g++ -g -Wall -std=c++17 \
-c ./src/*.cpp \
-I./src/ -I./build/ -include pch.hpp
I do not understand why adding another, irrelevant include-path solves anything. Weird.
My current working solution is to drop the -I include-path directive entirely, and specify a more complete path to build/pch.hpp:
g++ -g -Wall -std=c++17 \
-c ./src/*.cpp \
-include ./build/pch.hpp
This one works as expected. I'm not sure why it's necessary, though, and it's peculiar and inconvenient.
Is this how a PCH is supposed to be used? Why does my original line not work, and what am I meant to be doing instead?
From the documentation:
A precompiled header file is searched for when #include is seen in the compilation. As it searches for the included file (see Search Path in The C Preprocessor) the compiler looks for a precompiled header in each directory just before it looks for the include file in that directory. The name searched for is the name specified in the #include with ‘.gch’ appended. If the precompiled header file cannot be used, it is ignored.
For instance, if you have #include "all.h", and you have all.h.gch in the same directory as all.h, then the precompiled header file is used if possible, and the original header is used otherwise.
It means that the compiler must be able to find BOTH h-file and gch-file while building cpp. So they BOTH should in the same directory or the same include search path.
In order to try out FLTK, I have the following file structure:
project
|--main.cc
|--include
| |--FL
| | |--all FLTK header files
|--lib
| |--libfltk.a
| |--other fltk libraries
With the following content in main.cc:
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Window.H>
int main()
{
Fl_Window window(200, 200, "Window title");
Fl_Box box(0,0,200,200,"Hello, World!");
window.show();
return Fl::run();
}
Now when I run:
g++ -std=c++11 -c -o main.o main.cc -I include
g++ -std=c++11 -o main.exe main.o -L lib -lfltk
I get a whole bunch of errors after the second call to g++:
lib/libfltk.a(Fl.o):Fl.cxx:(.text$_ZL13image_to_iconPK12Fl_RGB_Imagebii+0xf3): undefined reference to `CreateDIBSection#24'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$_ZL13image_to_iconPK12Fl_RGB_Imagebii+0x1cf): undefined reference to `DeleteObject#4'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$_ZL13image_to_iconPK12Fl_RGB_Imagebii+0x258): undefined reference to `CreateBitmap#20'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$_ZL13image_to_iconPK12Fl_RGB_Imagebii+0x2a6): undefined reference to `DeleteObject#4'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$_ZL13image_to_iconPK12Fl_RGB_Imagebii+0x2b1): undefined reference to `DeleteObject#4'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$__tcf_1+0x5b): undefined reference to `OleUninitialize#0'
lib/libfltk.a(Fl.o):Fl.cxx:(.text$__tcf_1+0x83): undefined reference to `RestoreDC#8'
etc ...
The result is the same when I try to link the other FLTK libraries. Can anyone help me with that?
I use gcc from Windows, with MingW.
To solve this sort of problems is necessary to take help from fltk-config script. Therefore, it is enought to add line fltk-config --ldflags to compiler to avoid linker errors. Be sure to use "`" symbol around this command since this is the script and its should be executed.
I am trying to compile a code with gfortran. One of the first things that happens in the compilation is the creation of constants.mod. Soon after that gfortran tells me:
Fatal Error: Cannot read module file ‘constants.mod’ opened at (1), because it was created by a different version of GNU Fortran
Now here's the thing: This module file is created by the same gfortran that it's trying to read it. gfortran creates the thing itself and then 1 second later thinks the file was created by some other version! Any idea what's going on here?
You'll probably want to see the compile command:
mpif90 -c -O3 -ISDF/FORTRAN/include -I/usr/include -Iobj -Jobj -o obj/shared_data.o src/core/shared_data.F90
shared_data.F90 contains the module constants at the top of the file.
EDIT: Here's the compile command followed by the full error message:
$> mpif90 -c -O3 -ISDF/FORTRAN/include -I/usr/include -Iobj -Jobj -o obj/shared_data.o src/core/shared_data.F90
src/core/shared_data.F90:67:6:
USE constants
1
Fatal Error: Cannot read module file ‘constants.mod’ opened at (1), because it was created by a different version of GNU Fortran
compilation terminated.
UPDATE: I hope you'll agree this is weird. The file that is failing is in src/core. If I cd to src/core and issue this command:
mpif90 -c -O3 -I../../SDF/FORTRAN/include -I../../obj -J../../obj -o ../../obj/shared_data.o shared_data.F90
it compiles just fine! But then I clean everything out of the obj directory and I cd two levels up and issue:
mpif90 -c -O3 -ISDF/FORTRAN/include -Iobj -Jobj -o shared_data.o src/core/shared_data.F90
and it fails with the error I showed above! What is the difference??? Thanks.
When i compile with the following command:
g++ -fPIC -o obj/buffer.o buffer.cpp
I get the following error:
/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crt1.o:
In function _start': (.text+0x20): undefined reference tomain'
I am thought with the -fPIC flag, I didn't need a main function. I get this error with all of the cpp files. I do have a main.cpp that has the shared library functions in it. You can get the source code at the following:
git clone https://github.com/nterry/39DLL-4-Linux.git
Any ideas? I know that I can use the ld binary to put all of the o files in the an so once they're done, I just need help in building them all into shareable .o files
I think that I answered my question. I added a -c to the command and it seems to have worked. Here is the command I used:
g++ -fPIC -c -o obj/list.o list.cpp
That is one of several cpp files, and all seemed to work.