I am trying to update Anaconda's fork of c99-to-c89 to build with CMake. The project depends on Clang to parse C source code, but it does not require the use Clang as the compiler. I am using vcpkg to resolve dependencies for the project. My understanding is that Clang is part of the larger LLVM project, so I added llvm
along with the clang
component to my vcpkg.json
file and followed the guidance vcpkg printed out for how to import LLVM-related components but am still encountering linking errors.
Here's my vcpkg.json
file:
{
"name": "c99-to-c89",
"version": "1.0.4",
"description": "Tool to convert C99 code to MSVC-compatible C89. Includes fixes from Anaconda Distributions.",
"homepage": "https://github.com/AnacondaRecipes/c99-to-c89/",
"license": "Apache-2.0",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
},
{
"name": "llvm",
"default-features": false,
"features": [
"clang"
]
}
]
}
Here's my CMakeLists.txt
file:
cmake_minimum_required(VERSION 3.22)
project(C99_to_C89)
# Build steps for `c99conv`.
add_executable(c99conv convert.c)
# Locate and configure LLVM as a dependency, so we can pull in CLang from it.
find_package(LLVM CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${LLVM_CMAKE_DIR})
include(HandleLLVMOptions)
add_definitions(${LLVM_DEFINITIONS})
target_include_directories(c99conv PRIVATE ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS})
# Find the libraries that correspond to the LLVM components that we wish to use
llvm_map_components_to_libnames(llvm_libs Core)
# Link against LLVM libraries
target_link_libraries(c99conv PRIVATE ${llvm_libs} clangIndex)
# Build steps for `c99wrap`.
add_executable(c99wrap compilewrap.c)
I am getting these errors when building:
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getCString referenced in function find_token_index
convert.obj : error LNK2019: unresolved external symbol __imp_clang_disposeString referenced in function find_token_index
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getFileName referenced in function callback
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getSpellingLocation referenced in function get_token_offset
convert.obj : error LNK2019: unresolved external symbol __imp_clang_createIndex referenced in function convert
convert.obj : error LNK2019: unresolved external symbol __imp_clang_disposeIndex referenced in function convert
convert.obj : error LNK2019: unresolved external symbol __imp_clang_createTranslationUnitFromSourceFile referenced in function convert
convert.obj : error LNK2019: unresolved external symbol __imp_clang_disposeTranslationUnit referenced in function convert
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getTranslationUnitCursor referenced in function convert
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getCursorLocation referenced in function callback
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getCursorExtent referenced in function fill_struct_members
convert.obj : error LNK2019: unresolved external symbol __imp_clang_visitChildren referenced in function register_struct
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getCursorSpelling referenced in function find_anon_struct
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getTokenSpelling referenced in function find_token_index
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getTokenLocation referenced in function get_token_offset
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getTokenExtent referenced in function indent_for_token
convert.obj : error LNK2019: unresolved external symbol __imp_clang_tokenize referenced in function fill_struct_members
convert.obj : error LNK2019: unresolved external symbol __imp_clang_disposeTokens referenced in function fill_struct_members
convert.obj : error LNK2019: unresolved external symbol __imp_clang_getCursorKindSpelling referenced in function analyze_decl_context
I've searched around online and on SO for anything about this topic, but most posts I've come across are about how to handle linking errors when Clang is the toolchain, not when you're trying to link against Clang as a library. It's difficult finding keywords for this problem that are specific to this issue.
I came across another issue here on SO that seemed like mine, but the solution of needing an "import library for clang" didn't make sense to me.
I also tried grepping through the libraries included with LLVM and the only matches for the missing symbols were in libclang.dll
(it's a DLL since I'm on Windows). None of the LLVM components I see when running llvm-config --components
stand out to me as ones that would allow me to reference libclang
.
What do I need to do to pull this in?
It appears I don't need to reference LLVM in my CMakeLists.txt
file at all; I just needed to reference it in vcpkg.json
. Then, I could just depend on CLang and libclang
in the CMakeLists.txt
file. Here's what worked:
cmake_minimum_required(VERSION 3.22)
project(C99_to_C89)
# Build steps for `c99conv`.
add_executable(c99conv convert.c)
# Clang is provided by the LLVM project, which gets installed by vcpkg.
find_package(Clang CONFIG REQUIRED)
target_include_directories(c99conv PRIVATE ${CLANG_INCLUDE_DIRS})
# Link against Clang library
target_link_libraries(c99conv PRIVATE libclang)
# Build steps for `c99wrap`.
add_executable(c99wrap compilewrap.c)