0

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
jpmorr
  • 500
  • 5
  • 25
  • 1
    You didn't properly link any libraries, have you seen the responses to [this](https://stackoverflow.com/questions/8774593/cmake-link-to-external-library) question? – Kevin Jun 25 '20 at 17:25
  • @squareskittles OK, I didn't see that particular question during searching, and that may help with the shared library. I don't have it set in my makefile yet as it should compile with just the header files but the ````include_directories()```` don't seem to be working. The other answer seems to suggest that ````target_include_directories```` should be used but this is all a little confusing - I'm not sure what a target is. – jpmorr Jun 25 '20 at 17:35
  • Can you please provide the **full** error message pertaining to the include file? It is hard to understand what is going on from a *description* of the errors... – Kevin Jun 25 '20 at 17:41
  • 1
    Thanks, I don't see any issues with your `include_directories()` calls. The error message is a **linker** error, because you haven't actually linked the library `libcoupling.so` to your executable. Again, please see the responses to my earlier linked question as they are generally applicable to *any* external library. In particular, you could try [this](https://stackoverflow.com/a/10550334/3987854) response to fix the issue - as you can see, you are *missing* the `target_link_libraries` command. – Kevin Jun 25 '20 at 18:40
  • @squareskittles Thanks. This indeed was the problem - the linker was not set properly. – jpmorr Jun 26 '20 at 09:53

1 Answers1

0

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.

J Vines
  • 182
  • 1
  • 16