I am trying to include a 3rd party library in my first C++ project.
Here is the file structure:
Here is the code:
If I try to compile it, I get the following error:
Starting build... /usr/bin/g++ -g /home/?/projects/c++/test.cpp -o /home/?/projects/c++/test
/usr/bin/ld: /tmp/cci5qRjP.o: in function `main': /home/?/projects/c++/test.cpp:7: undefined reference to `omp::HandEvaluator::HandEvaluator()'
/usr/bin/ld: /tmp/cci5qRjP.o: in function `omp::Hand::Hand(unsigned int)': /home/?/projects/c++/include/OMPEval/omp/Hand.h:49: undefined reference to `omp::Hand::CARDS'
/usr/bin/ld: /tmp/cci5qRjP.o: in function `omp::Hand::empty()': /home/?/projects/c++/include/OMPEval/omp/Hand.h:114: undefined reference to `omp::Hand::EMPTY'
/usr/bin/ld: /tmp/cci5qRjP.o: in function `omp::HandEvaluator::perfHash(unsigned int)': /home/?/projects/c++/include/OMPEval/omp/HandEvaluator.h:39: undefined reference to `omp::HandEvaluator::PERF_HASH_ROW_OFFSETS'
/usr/bin/ld: /tmp/cci5qRjP.o: in function `unsigned short omp::HandEvaluator::evaluate<true>(omp::Hand const&) const': /home/?/projects/c++/include/OMPEval/omp/HandEvaluator.h:27: undefined reference to `omp::HandEvaluator::LOOKUP'
/usr/bin/ld: /home/?/projects/c++/include/OMPEval/omp/HandEvaluator.h:31: undefined reference to `omp::HandEvaluator::FLUSH_LOOKUP'
collect2: error: ld returned 1 exit status
Build finished with error(s). The terminal process failed to launch (exit code: -1).
Terminal will be reused by tasks, press any key to close it.
The code is taken for the documentation of the library.
c_cpp_properties.json
launch.json
tasks.json
Wherever that tasks.json came from, it is not adequate for a complex project containing multiple source files. It compiles and tries to link only a single .cpp file; this is doomed to failure when there are multiple .cpp files that are supposed to work together.
You have a file named Makefile in your project directory... updating tasks.json to run make and let make run the compiler and linker would be a good start... but you should also expect to modify the Makefile each time you add new files to your project.
Related
I'm building a static library for a small project, and when I compile it with ar, it correctly links.
When I go to include the relevant header file and link the test script to the archive;
LINK = -lpthread -lcryptopp -L./path/to/archive/ -luttu
r: ../inc/uttu.hpp
g++ -std=c++20 rnet.cpp -o r.out $(LINK)
I get linker errors;
/usr/bin/ld: /tmp/cc7h6RHu.o: in function `main':
rnet.cpp:(.text+0x263): undefined reference to `np::np()'
/usr/bin/ld: rnet.cpp:(.text+0x317): undefined reference to `np::np()'
/usr/bin/ld: ./../exe//libuttu.a(peer.o): in function `Peer::Connect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
/home/uton/code/Concord/uttu/src/peer.cpp:43: undefined reference to `void np::target<np::_tf>(np::_tf)'
/usr/bin/ld: ./../exe//libuttu.a(relay.o): in function `Relay::Foward()':
/home/uton/code/Concord/uttu/src/relay.cpp:40: undefined reference to `np::np()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:8: r] Error 1
Running ar t libuttu.a returns
linux.o
uttu.o
timeout.o
peer.o
relay.o
sec.o
np.o
My test script includes the main header file, uttu.hpp, which itself refers to the np header file, under the name of protocols.hpp
The path to the archive file is correct, the archive itself contains the correct object file, and the test script refers to the main header file, which includes the correct definitions.
I'm stuck on what could be going wrong.
After reading this SO question, I realized that I had missed an overridden virtual member.
I used the python amalmagate file to compile the json library. Now when I run the c++ code, I keep getting this error.
/usr/bin/ld: msort.cc:(.text+0x255): undefined reference to Json::Value::~Value()' /usr/bin/ld: msort.cc:(.text+0x264): undefined reference to Json::Value::~Value()'
/usr/bin/ld: msort.cc:(.text+0x278): undefined reference to Json::Value::operator[](int)' /usr/bin/ld: msort.cc:(.text+0x28c): undefined reference to Json::Value::Value(char const*)'
/usr/bin/ld: msort.cc:(.text+0x2a7): undefined reference to `Json::Value::get(char const*, Json::Value const&) const'
This is what I used to download the jsoncpp library
git clone https://github.com/open-source-parsers/jsoncpp.git
cd jsoncpp
python amalgamate.py
The code I ran to compile: g++ msort.cc -o msort
I understand that this means that the library is not connecting with my code. Any idea how I can fix this?
If you read the instructions for the amalgamated library you will see that you need to build with the library source file dist/jsoncpp.cpp:
g++ msort.cc dist/jsoncpp.cpp -o msort
This question already has answers here:
CMake link to external library
(6 answers)
Closed 2 years ago.
I've just started to use CLion as my IDE after mainly using code::blocks on Linux for the last year or so. However I'm finding it really difficult to set up a project that worked and compiled fine in code::blocks because I just don't understand cmake yet.
Here's a quick description of my project - it consists of a main file that is calling a few header and source files, which all in the same directory. In the main file I'm also calling an external header file ("coupling.h", which is located in "/opt/package/API_SRC_Files/Coupling") which describes some classes relating to coupling to that software. The "coupling.h" file in turn references some files in "/opt/package/API_SRC_Files/Coupling". I also need to link to a shared library file "libcoupling.so" that is located in "/opt/package/lib".
Setting this up in code::blocks was pretty easy - just go to build options, and the respective paths to the search directories, and the path to the linked file and then build. Compiles in a few seconds.
I've tried to setup the project in CLion and CMake but I'm truly lost and I don't really understand why CMake is not finding the "coupling.h" file and throws countless "undefined reference to " errors. I'm sure I'll also have a problem setting up the shared library and I'm scared to even think about the difference in debug and release versions at the moment!
Here's my current CMake.txt file, hopefully someone can help. I'm using CLion 2020.1 on Fedora.
cmake_minimum_required(VERSION 3.16)
project(MBD VERSION 0.6.1)
set(CMAKE_CXX_STANDARD 14)
# add extra include directories
include_directories(.)
include_directories(/opt/package/API_SRC_Files)
include_directories(/opt/package/API_SRC_Files/Core)
include_directories(/opt/package/API_SRC_Files/Coupling)
set(PROJECT_HEADERS
coupling_utilities.h
geometry.h
io.h
shapelib.h
pid.h
spline.h
)
set(PROJECT_SOURCES
main.cpp
io.cpp
coupling_utilities.cpp
shapelib.cpp
pid.cpp
)
# add extra lib directories
link_directories(/opt/package/lib)
add_executable(MBD ${PROJECT_SOURCES} ${PROJECT_HEADERS})
Here's the error log from the output related to the include_directories():
/snap/clion/114/bin/cmake/linux/bin/cmake --build /home/user/CLionProjects/mbd/cmake-build-debug --target mbd -- -j 24
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/CLionProjects/mbd/cmake-build-debug
[ 16%] Linking CXX executable mbd
/usr/bin/ld: CMakeFiles/mbd.dir/main.cpp.o: in function `main':
/home/user/CLionProjects/mbd/main.cpp:224: undefined reference to `NApi::Coupling::getGeometryId(char const*, int&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:260: undefined reference to `NApi::Coupling::getTimeStep(double&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:268: undefined reference to `NApi::Coupling::getTime(double&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:273: undefined reference to `NApi::Coupling::setTime(double const&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:276: undefined reference to `NApi::Coupling::getTime(double&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:285: undefined reference to `NApi::Coupling::setGridCellSize(double const&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:288: undefined reference to `NApi::Coupling::setNumberOfCores(int const&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:343: undefined reference to `NApi::Coupling::getGeometryPosition(int, NApi::C3dValue&, NApi::C3x3Matrix&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:345: undefined reference to `NApi::Coupling::getGeometryTranslation(int, NApi::C3dValue&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:348: undefined reference to `NApi::Coupling::getGeometryVelocity(int, NApi::C3dValue&, NApi::C3dValue&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:442: undefined reference to `NApi::Coupling::isConnected() const'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:444: undefined reference to `NApi::Coupling::getGeometryForces(int, NApi::C3dValue&, NApi::C3dValue&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:531: undefined reference to `NApi::Coupling::isConnected() const'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:534: undefined reference to `NApi::Coupling::setGeometryMotion(int, NApi::C3dValue const&, NApi::C3x3Matrix const&, NApi::C3dValue const&, NApi::C3dValue const&, double, bool)'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:554: undefined reference to `NApi::Coupling::isConnected() const'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:556: undefined reference to `NApi::Coupling::simulate(double const&, double)'
/usr/bin/ld: CMakeFiles/mbd.dir/main.cpp.o: in function `__static_initialization_and_destruction_0(int, int)':
/home/user/CLionProjects/mbd/main.cpp:74: undefined reference to `NApi::Coupling::ICoupling()'
/usr/bin/ld: /home/user/CLionProjects/mbd/main.cpp:74: undefined reference to `NApi::Coupling::~ICoupling()'
/usr/bin/ld: CMakeFiles/mbd.dir/coupling_utilities.cpp.o: in function `connect(NApi::Coupling&)':
/home/user/CLionProjects/mbd/coupling_utilities.cpp:54: undefined reference to `NApi::Coupling::initialiseCoupling()'
/usr/bin/ld: /home/user/CLionProjects/mbd/coupling_utilities.cpp:67: undefined reference to `NApi::Coupling::connectCoupling(bool, char const*)'
/usr/bin/ld: /home/user/CLionProjects/mbd/coupling_utilities.cpp:90: undefined reference to `NApi::Coupling::connectCoupling(bool, char const*)'
/usr/bin/ld: CMakeFiles/mbd.dir/coupling_utilities.cpp.o: in function `getResumeTimestep(NApi::Coupling&, double, double)':
/home/user/CLionProjects/mbd/coupling_utilities.cpp:109: undefined reference to `NApi::Coupling::getNumberOfTimesteps(unsigned int&)'
/usr/bin/ld: /home/user/CLionProjects/mbd/coupling_utilities.cpp:136: undefined reference to `NApi::Coupling::getTimesteps(double*, unsigned int&, unsigned int)'
collect2: error: ld returned 1 exit status
gmake[3]: *** [CMakeFiles/mbd.dir/build.make:144: mbd] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/mbd.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/mbd.dir/rule] Error 2
gmake: *** [Makefile:118: mbd] Error 2
Here is how I would write the cmakelists.txt file:
cmake_minimum_required(VERSION 3.16)
project(MBD VERSION 0.6.1)
set(CMAKE_CXX_STANDARD 14)
set(API_SRC_Files /opt/package/API_SRC_Files) # ${API_SRC_Files}
set(SRC_FILES
main.cpp
coupling_utilities.h coupling_utilities.cpp
geometry.h
io.h io.cpp
pid.h pid.cpp
shapelib.h shapelib.cpp
spline.h
)
# add extra include directories
include_directories(
includes
.
${API_SRC_Files}
${API_SRC_Files}/Core
${API_SRC_Files}/Coupling
)
# add extra lib directories
link_directories(/opt/package/lib)
add_executable(${PROJECT_NAME} ${SRC_FILES})
Use something like the API_SRC_Files variable for two reasons: reduces errors from having to repeat the same path information, makes it easier if the library is ever moved to a new location. The same thing with using the PROJECT_NAME variable. The comment is to remind myself how to utilize the variable later on in the file.
Combine your SRC_FILES and SRC_HEADERS into one array with source and matching header on the same line. This helps to make sure both are listed. Please note when you tell Clion you want to add a new C++ Class, it will be in the form class.cpp class.h, and not alphabetized. I always list the main.cpp, first.
The dot, ., in the include_directories may or may not be necessary.
Hope this helps.
I am trying to follow some sqlite C++ tutorial to be able to access a database from within C++ code on Linux. sqlite3 is installed and working, but when I try to compile the example code given on the link (Create a Table) I get the following error:
g++ build/test.o -o bin/test -pthread -L lib
build/test.o: In function `main':
/home/alexander/Projects/Test/src/test.cpp:22: undefined reference to `sqlite3_open'
/home/alexander/Projects/Test/src/test.cpp:24: undefined reference to `sqlite3_errmsg'
/home/alexander/Projects/Test/src/test.cpp:39: undefined reference to `sqlite3_exec'
/home/alexander/Projects/Test/src/test.cpp:42: undefined reference to `sqlite3_free'
/home/alexander/Projects/Test/src/test.cpp:46: undefined reference to `sqlite3_close'
collect2: error: ld returned 1 exit status
Do I need to install something else? Or do I need to set some paths?
I have no practice in compiling straight from the shell.
In CodeBlocks it is necessary to point the paths of the “sqlite3.h” header and the “libsqlite3.so” dll.
If the dll is not specified in Linker Settings, exactly the mentioned problem occurs.
I had written my program using XCode. It works without any problems on the Mac. I was told that our projects would be compiled on Linux machines so I wanted to make sure it works on Linux before submitting. When I tried to compile on Linux, it gave me some reference errors:
/tmp/cckwoehj.o: In function `main':
main.cpp:(.text+0x9): undefined reference to `ReadFile()'
/tmp/cckwoehj.o: In function `leftSearch(NODE*, int)':
main.cpp:(.text+0x38b): undefined reference to `conflict(int**)'
main.cpp:(.text+0x3ca): undefined reference to `removeAllRowsWithLiteral(int**, int)'
main.cpp:(.text+0x3ec): undefined reference to `removeAllSpecifiedLiteral(int**, int)'
main.cpp:(.text+0x4ec): undefined reference to `conflict(int**)'
main.cpp:(.text+0x522): undefined reference to `unitPropagation(int**)'
main.cpp:(.text+0x538): undefined reference to `conflict(int**)'
/tmp/cckwoehj.o: In function `rightSearch(NODE*, int)':
main.cpp:(.text+0x992): undefined reference to `conflict(int**)'
main.cpp:(.text+0x9d4): undefined reference to `removeAllRowsWithLiteral(int**, int)'
main.cpp:(.text+0x9f3): undefined reference to `removeAllSpecifiedLiteral(int**, int)'
main.cpp:(.text+0xaf3): undefined reference to `conflict(int**)'
main.cpp:(.text+0xb29): undefined reference to `unitPropagation(int**)'
main.cpp:(.text+0xb3f): undefined reference to `conflict(int**)'
collect2: ld returned 1 exit status
The stuff I found online all talks about templates. I don't use templates. I also found one about a 32 and 64 bit OS problem which I do not have.
I have a function called ReadFile that is declared in a header. I call it from main and include that header file in main. I am not sure what the problem is. If OS X compiles and runs and Linux doesn't, I am assuming there is something OS X does internally that it thinks is obvious but Linux is not written that way. Is this a linker error? I think OS X would be programmed to do that internally.
You're declaring your functions in a header, but there's no definition, leading to undefined references when you try to turn main.cpp into an executable.
You need to compile all your source files and link them together (in the right order).
g++ -c ReadFile.cpp
#...
g++ -c main.cpp
g++ main.o ... ReadFile.o -o my_executable
Where the object files to the right rely on no unresolved symbols defined in the object files to its left on the commandline.
XCode is an IDE so I guess it handles the linking order for you.
To handle all this stuff automatically you'll have to also use an IDE and/or write a Makefile.
If you insist in a single command, yes, you can, as long as you include all source files in the line (e.g. g++ *.cpp), but this forces a full recompilation for every single change.