How to include C static libraries in CMAKE project

2019-02-20 23:12发布

问题:

I am trying to learn Core Foundation with C/C++. I use JetBrains CLion that uses CMAKE.

The problem is - I dunno how to include proper static libraries in C/C++ Makefile project on Mac.

I need to link static library CFNetwork to my project in order to fix linking problems.

Could you give me a quick hint?

My case:

#include <CFNetwork/CFNetwork.h>
#include <iostream>

int main() {
    CFStringRef bodyString = CFSTR(""); // Usually used for POST data
    CFDataRef bodyData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
        bodyString, kCFStringEncodingUTF8, 0);

    CFStringRef headerFieldName = CFSTR("X-My-Favorite-Field");
    CFStringRef headerFieldValue = CFSTR("Dreams");

    CFStringRef url = CFSTR("http://www.apple.com");
    CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);

    CFStringRef requestMethod = CFSTR("GET");
    CFHTTPMessageRef myRequest =
        CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL,
                kCFHTTPVersion1_1);

    CFHTTPMessageSetBody(myRequest, bodyData);
    CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue);
    CFDataRef mySerializedRequest = CFHTTPMessageCopySerializedMessage(myRequest);

    return 0;
}

I can compile this but linker outputs me the following:

"/Applications/CLion EAP.app/Contents/bin/cmake/bin/cmake" --build /Users/nickolay/Library/Caches/clion10/cmake/generated/3546f185/3546f185/Debug --target test001 -- -j 8
Scanning dependencies of target test001
[100%] Building CXX object CMakeFiles/test001.dir/main.cpp.o
Linking CXX executable test001
Undefined symbols for architecture x86_64:
  "_CFHTTPMessageCopySerializedMessage", referenced from:
      _main in main.cpp.o
  "_CFHTTPMessageCreateRequest", referenced from:
      _main in main.cpp.o
  "_CFHTTPMessageSetBody", referenced from:
      _main in main.cpp.o
  "_CFHTTPMessageSetHeaderFieldValue", referenced from:
      _main in main.cpp.o
  "_CFStringCreateExternalRepresentation", referenced from:
      _main in main.cpp.o
  "_CFURLCreateWithString", referenced from:
      _main in main.cpp.o
  "___CFConstantStringClassReference", referenced from:
      CFString in main.cpp.o
      CFString in main.cpp.o
      CFString in main.cpp.o
      CFString in main.cpp.o
      CFString in main.cpp.o
  "_kCFAllocatorDefault", referenced from:
      _main in main.cpp.o
  "_kCFHTTPVersion1_1", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [test001] Error 1
make[2]: *** [CMakeFiles/test001.dir/all] Error 2
make[1]: *** [CMakeFiles/test001.dir/rule] Error 2
make: *** [test001] Error 2

回答1:

Finally resolved.

Thanks to this resource: http://raycast.net/clion-multiple-binaries

This is how my CMAKE file looks like and everything links:

cmake_minimum_required(VERSION 2.8.4)
project(test001)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)

find_library(corefoundation_lib CoreFoundation)
find_library(cfnetwork_lib CFNetwork)

set(frameworks
    ${cfnetwork_lib}
    ${corefoundation_lib})

add_executable(test001 ${SOURCE_FILES})
target_link_libraries(test001 ${frameworks})


回答2:

I'm not 100% sure if this is what you ment but you link C static libraries by giving -llibrary flag to your compiler where the name of the library file is liblibrary.a. If the library isn't in some default library location (idk what it is for mac) you can specify the path with -L flag.