0

I'm new to C development.

A I built a library (static) in CLion

library.h

#ifndef MYLIB_LIBRARY_H
#define MYLIB_LIBRARY_H

int add(int a, int b);
int sub(int a, int b);

#endif

library.c

#include "library.h"
#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int sub(int a, int b) {
    return a - b;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(MyLib)

set(CMAKE_C_STANDARD 99)

set(SOURCE_FILES library.c library.h)
add_library(MyLib ${SOURCE_FILES})


B. Created C Executable project called App and copied libMyLib.a into lib directory of App.

main.c

#include <stdio.h>
#include "library.h" // error

int main() {
    printf("Hello, World!\n", add(1, 2)); // error
    return 0;
}

CMakeLists.txt of the project App and specified folder for the linker.

cmake_minimum_required(VERSION 3.6)
project(App)

set(CMAKE_C_STANDARD 99)

set(SOURCE_FILES main.c)
link_directories(${PROJECT_SOURCE_DIR}/lib)
add_executable(App ${SOURCE_FILES})

Question. How can I make my program work using static library?

2 Answers2

0

There's a couple of things I had to change to get your example to work:

  1. Create an include directory in the App directory.
  2. Put library.h in this include directory.
  3. Modify the project CMakeLists.txt file:

    cmake_minimum_required(VERSION 3.6)
    project(App)
    
    set(CMAKE_C_STANDARD 99)
    set(SOURCE_FILES main.c)
    # get libMyLib.a
    find_library(MY_LIB
        NAMES libMyLib.a
        PATHS ${PROJECT_SOURCE_DIR}/lib)
    # get library.h
    include_directories(${PROJECT_SOURCE_DIR}/include)
    
    add_executable(App ${SOURCE_FILES})
    # link App with libMyLib.a
    target_link_libraries(App ${MY_LIB})
    
Jonathan
  • 1,382
  • 1
  • 13
  • 13
  • Thanks, it worked. I've another question, what are the conventions of distributing your library. How people expect 3rd party libraries, seems I'll distribute `.a` and `.h` files together. Also should I have placed both `libMyLib.a` and `library.h` within the include folder? –  Feb 26 '17 at 06:27
  • any suggestion please? –  Feb 26 '17 at 17:44
  • 1
    I don't have any experience distributing libraries, however, I think the convention is to have lib/ directory for `.a` and `.so` files and have an include directory for `.h` files. You might also consider adding documentation and testing for the library. Here's a link to the jsoncpp library repo which uses cmake: https://github.com/open-source-parsers/jsoncpp. They actually provide the source files and header files needed to build the library and the end user is the one who builds it using cmake/make. – Jonathan Feb 26 '17 at 21:20
0

This line:

printf("Hello, World!\n", add(1, 2)); // error

is generating an error at compile time, not link time

The reason is the printf() function is being passed as the first argument (the format string) Hello, World!\n and the second argument: add(1,2) However, there is no format specifier in the format string for the results of the call to add()

The compiler will output the message:

warning: too many arguments for format [-Wformat-extra-args]

There is no reason to be looking at the Cmakelists.txt file until after correcting the compile problems

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • thanks eventually i fixed it after the other answer about cmake, i wanna know what's the directory structure when it comes to distributing 3rd party c libraries, and what's the convention of placing them in your project? –  Feb 26 '17 at 17:43
  • 1
    the simplest way is to place the libraries in a (your preference) directory, then place a link in a place that the linker will normally look, for instance in `/usr/lib/` – user3629249 Feb 26 '17 at 20:32
  • from cosmetic point of view, my library project prefixed my `.a` filename with `lib`, I renamed manually but compiler complained when linking. how can i configure to create .a name I like? –  Feb 27 '17 at 02:31
  • @User794691, The linker has its' own rules and syntax. It matters not what you might like, It matters what the linker likes. – user3629249 Feb 28 '17 at 08:38