0

I have the following code that works perfectly with gcc by running the command:

gcc -L ~/Installed/C_LIBS/cmocka/lib -I ~/Installed/C_LIBS/cmocka/include hello.c -lcmocka -o hello 

When I try to convert that to a CMakeLists.txt it breaks after running cd build && cmake .. && make with the following error codes:

Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/main.c.o
[100%] Linking C executable hello
ld: library not found for -lcmocka
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [hello] Error 1
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
make: *** [all] Error 2

I have the code setup like this:

    my-proj/
     - CMakeLists.txt
     - main.c
     - build/

Here are my files:

main.c

    #include <stdarg.h>
    #include <stddef.h>
    #include <setjmp.h>
    #include <cmocka.h>
    /* A test case that does nothing and succeeds. */
    static void null_test_success(void **state) {
        (void) state; /* unused */
    }
    int main(void) {
        const struct CMUnitTest tests[] = {
            cmocka_unit_test(null_test_success),
        };
        return cmocka_run_group_tests(tests, NULL, NULL);
    }

CMakeLists.txt

    cmake_minimum_required(VERSION 2.8.9)
    project (hello)

    include_directories(
    SYSTEM ~/Installed/C_LIBS/cmocka/lib
    SYSTEM ~/Installed/C_LIBS/cmocka/include
    )

    add_executable(hello main.c)
    target_link_libraries(hello cmocka)

Can someone please tell me what I am doing wrong here? Also maybe point me in the direction of where to learn CMake better?

Ry10p
  • 312
  • 1
  • 2
  • 11
  • 1
    include_directories() maps to `-I`, it has no impact on `-L` –  May 21 '20 at 22:11
  • What maps to the -L ? – Ry10p May 21 '20 at 22:12
  • https://cmake.org/cmake/help/v3.17/command/target_link_directories.html – drescherjm May 21 '20 at 22:13
  • 1
    The clean way to do things would be to use `find_library()`, but since you have your local path hardcoded in the CMakeLists.txt , you should just link against the absolute path of the library. `link_directories()` and `target_link_directories()` are rarely the right answer. –  May 21 '20 at 22:15

1 Answers1

2

The include_directories() command only affects header search paths (stuff that is used through #include). It has no effect on library search paths.

Since you know the full path of the library, you should just be linking directly against said full path:

 target_link_libraries(hello ~/Installed/C_LIBS/cmocka/lib/libcmocka.a)

However, this is just patching your CMakeLists.txt. What you should be doing is use CMake's library functions, which will be a lot more flexible:

# Include dir
find_path(MOCKA_INCLUDE_DIR
  NAMES cmocka.h
  PATHS ~/Installed/C_LIBS/cmocka/include
)

#library itself
find_library(MOCKA_LIBRARY
  NAMES cmocka
  PATHS ~/Installed/C_LIBS/cmocka/lib
)

target_include_directories(hello PRIVATE ${MOCKA_INCLUDE_DIR})
target_link_libraries(hello ${MOCKA_LIBRARY})
  • I am now getting some errors with the cmake portion of the build, but I think I am starting to understand what you are saying. I really appreciate the help. – Ry10p May 21 '20 at 22:31
  • GOT IT!! Thank you so much!! – Ry10p May 21 '20 at 22:45