Compiling for testing vs debug

Hello,

I am fairly new to CLion, but I like it a lot thus far. My personal favorite thing is that everything is done through a consistent and easy to understand build system like CMake.

Unfortunately, I cannot figure out something that I want to be able to do:

I have a project in CLion called Crypto_Project which I am writing currently for a school assignment. I wanted to do unit-testing for this as well, so I managed to create another executable (besides the default one) in the CMakeLists.txt which compiles with a library called cmocka that I also built and installed on my system. My CMakeLists.txt file is included below:

 
cmake_minimum_required(VERSION 3.3)
project(Crypto_Project)

include_directories(/usr/local/include)
find_library(CMOCKA_LIBRARY libcmocka.so.0)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -lcmocka")

#Normal executable
set(SOURCE_FILES crypto_project.c ap_int.c ap_int.h)
add_executable(Crypto_Project ${SOURCE_FILES})
target_link_libraries(Crypto_Project ${CMOCKA_LIBRARY})

#Testing executable
set(TESTING_SOURCE_FILES ap_int_tests.c ap_int.c ap_int.h)
add_executable(Test_Crypto_Project ${TESTING_SOURCE_FILES})

target_link_libraries(Test_Crypto_Project ${CMOCKA_LIBRARY})

As you can see there are two executables there, the normal crypto_project executable and the testing executable which runs a series of cmocka unit tests. The problem is that in the current configuration, I can compile and run the testing executable just fine, however, I cannot compile the normal executable without linking it to cmocka as well. For some reason when I remove the line: target_link_libraries(Crypto_Project ${CMOCKA_LIBRARY}) I get the following error: /home/eugene/.CLion12/system/cmake/generated/5c245747/5c245747/Debug/Crypto_Project: error while loading shared libraries: libcmocka.so.0: cannot open shared object file: No such file or directory This makes sense because I know I am trying to compile with the -lcmocka flag, however, I do not understand how I can compile the "normal" executable without the -lcmocka flag, while compiling the testing executable with the -lmocka flag.

I should note that my ultimate goal is to have the normal executable be compile-able on a system where cmocka is not installed and if someone wants to run the unit tests then they would have to install cmocka before compiling the testing executable.


If anyone has any suggestions on how to get this working properly I would really appreciate it. Thank you in advance!

4 comments
Comment actions Permalink

Hi Eugene.

You need to find CMocka library via find_package() command. CMake doesn't come with bundled helper for CMocka, so you need to download it (for example, here: https://github.com/CESNET/libyang/blob/master/CMakeModules/FindCMocka.cmake). Create a folder cmake/Modules/ under your project root, and in the root CMakeLists.txt, include the following code: set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/“).


After that all you need to do is to write:
find_package(CMocka REQUIRED)
target_include_directories(Test_Crypto_Project ${CMOCKA_INCLUDE_DIR})
target_link_libraries(Test_Crypto_Project ${Test_Crypto_Project})

also remove include_directories(/usr/local/include), find_library(CMOCKA_LIBRARY libcmocka.so.0) and -lcmocka from your CMakeLists. This way your Crypto_Project target wouldn't be dependent of CMocka and all the compiler flags will be handled by CMake in cross-platform compiler-agnostic way. You can find out more here: https://cmake.org/Wiki/CMake:How_To_Find_Libraries

0
Comment actions Permalink

Hello!


Thanks for your help. I think I made the modifications you were talking about correctly, but it is telling me that: Error:target_include_directories called with invalid arguments

I was wondering whether this had to do with the lines:
find_path(CMOCKA_INCLUDE_DIR
    NAMES
        cmocka.h
    PATHS
        ${CMOCKA_ROOT_DIR}/include
)


find_library(CMOCKA_LIBRARY
    NAMES
        cmocka
    PATHS
        ${CMOCKA_ROOT_DIR}/include
)
In the module file you linked. Is it possible that the issue is with my library paths? I was under the impression that they are fairly standard:
/usr/local/include/cmocka.h
/usr/local/lib/libcmocka.so.0

Just in case I have included my modified CMakeLists.txt file:

cmake_minimum_required(VERSION 3.3)
project(Crypto_Project)


set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")


# Source Files
set(TESTING_SOURCE_FILES ap_int_tests.c ap_int.c ap_int.h)
set(SOURCE_FILES crypto_project.c ap_int.c ap_int.h)


set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")


#Normal executable
add_executable(Crypto_Project ${SOURCE_FILES})


#Testing executable
find_package(CMocka REQUIRED)
add_executable(Test_Crypto_Project ${TESTING_SOURCE_FILES})
target_include_directories(Test_Crypto_Project ${CMOCKA_INCLUDE_DIR})
target_link_libraries(Test_Crypto_Project ${Test_Crypto_Project})

0
Comment actions Permalink
Hi Eugene.

Sorry, I’ve made a typo in the example. The correct line is
target_link_libraries(Test_Crypto_Project ${
CMOCKA_LIBRARIES})


This means “link Test_Crypto_Project executable with CMOCKA_LIBRARIES (found by find_package)”.
0
Comment actions Permalink

It works perfectly now. Thank you so much!

0

Please sign in to leave a comment.