0

I'm including this library as an external project. Based on the documentation, with some small tweaks, I have this:

# LIEF dependency
# ===========================
set(LIEF_PREFIX       "${CMAKE_CURRENT_BINARY_DIR}/LIEF")
set(LIEF_INSTALL_DIR  "${LIEF_PREFIX}")
set(LIEF_INCLUDE_DIRS "${LIEF_PREFIX}/include")

# LIEF static library
set(LIEF_LIBFILE
  "${LIEF_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}LIEF${CMAKE_STATIC_LIBRARY_SUFFIX}")

# URL of the LIEF repo (Can be your fork)
set(LIEF_GIT_URL "https://github.com/lief-project/LIEF.git")

# LIEF's version to be used (can be 'master')
set(LIEF_VERSION 0.11.5)

# LIEF compilation config
set(LIEF_CMAKE_ARGS
  -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
  -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
  -DLIEF_DOC=off
  -DLIEF_PYTHON_API=off
  -DLIEF_EXAMPLES=off
  -DLIEF_OAT=off
  -DLIEF_DEX=off
  -DLIEF_VDEX=off
  -DLIEF_ART=off
  -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
  -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
)

# Specify MSVCRT on MSVC
if(MSVC)
  list(APPEND ${LIEF_CMAKE_ARGS} -DLIEF_USE_CRT_RELEASE=MT)
  list(APPEND ${LIEF_CMAKE_ARGS} -DLIEF_USE_CRT_DEBUG=MTd)
endif()

# External project
ExternalProject_Add(LIEF_extproj
  PREFIX           "${LIEF_PREFIX}"
  GIT_REPOSITORY   ${LIEF_GIT_URL}
  GIT_TAG          ${LIEF_VERSION}
  INSTALL_DIR      ${LIEF_INSTALL_DIR}
  CMAKE_ARGS       ${LIEF_CMAKE_ARGS}
  BUILD_BYPRODUCTS ${LIEF_LIBFILE}
  UPDATE_COMMAND   ""
)

However, the original docs simply included the directories and linked separately. Can I somehow wrap these into a single target, where if I link to that target I get everything from that library?

EDIT: My current attempt at setting up an imported target is this:

add_library(LIEF_depimpl STATIC IMPORTED)
set_target_properties(LIEF_depimpl PROPERTIES
  IMPORTED_LOCATION ${LIEF_LIBFILE}
  INTERFACE_INCLUDE_DIRECTORIES ${LIEF_INCLUDE_DIRS}
)
add_dependencies(LIEF_depimpl LIEF_extproj)

When I use target_link_libraries() to link LIEF against my project, CMake generates successfully, but then I get an error in the generated makefile.

add_executable(testapp lief-test.cpp)
...
# Link the executable with LIEF
target_link_libraries(testapp PUBLIC ${LIEF_depimpl})
itzjackyscode
  • 970
  • 9
  • 27
  • But why not use `add_subdirectory`? Or `find_package(LIEF)`? – KamilCuk Jul 26 '21 at 20:43
  • I would use find_package, but I'd have to precompile the library. add_subdirectory doesn't give separation between my project and its dependencies. – itzjackyscode Jul 26 '21 at 21:21
  • Yes, you could create an IMPORTED library target, which can accumulate all properties of the external project: libraries, include directories, etc. Do not forget to `add_dependencies` between that library target and the target defined for ExternalProject (`LIEF_extproj` in your case). – Tsyvarev Jul 26 '21 at 21:43
  • @Tsyvarev I have edited the question for clarity. – itzjackyscode Jul 26 '21 at 22:10
  • "but then I get an error in the generated makefile." is not very descriptive. Also, a *dereference* `${LIEF_depimpl}` is a wrong way to refer to the **target** with name `LIEF_depimpl`. Correct way for link with the target: `target_link_libraries(testapp PUBLIC LIEF_depimpl)`. – Tsyvarev Jul 26 '21 at 22:42

1 Answers1

0

The syntax for target_link_libraries() isn't what I thought it was. The dependency variable should not be expanded, like this:

target_link_libraries(testapp PUBLIC LIEF_depimpl)

In addition, CMake will throw an error if it can't find the include directories for an external project, so you should create that folder in your CMake file like so:

set(LIEF_INCLUDE_DIRS "${LIEF_PREFIX}/include")
file(MAKE_DIRECTORY ${LIEF_INCLUDE_DIRS})
itzjackyscode
  • 970
  • 9
  • 27