Я использую cmake для создания Makefile для проекта. В верхний CMakeLists.txt мне нужно включить некоторые подмодули. Так что это как:
include(cmake/Modules/pcre-8.40.cmake)
include(cmake/Modules/curl-7.64.1.cmake)
include(cmake/Modules/openssl-1.1.1.cmake)
curl-7.64.1.cmake выглядит так:
include(ExternalProject)
set (PCAP_ROOT ${CMAKE_BINARY_DIR}/third_party/curl)
set (PCAP_LIB_DIR ${PCAP_ROOT}/lib)
set (PCAP_INCLUDE_DIR ${PCAP_ROOT}/include)
set (OPENSSL_DIR ${CMAKE_BINARY_DIR}/third_party/openssl/build)
set (OPENSSL_I_DIR ${OPENSSL_DIR}/include)
set (OPENSSL_L_DIR ${OPENSSL_DIR}/lib)
set (PCAP_CONFIGURE cd ${PCAP_ROOT}/src/curl-7.64.1 && cmake -DOPENSSL_ROOT_DIR=${OPENSSL_DIR} -DOPENSSL_INCLUDE_DIR=${OPENSSL_I_DIR} -DOPENSSL_SSL_LIBRARY=${OPENSSL_L_DIR}/libssl.a -DOPENSSL_CRYPTO_LIBRARY=${OPENSSL_L_DIR}/libcrypto.a -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${PCAP_ROOT} -DBUILD_CURL_EXE=OFF . -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
set (PCAP_MAKE cd ${PCAP_ROOT}/src/curl-7.64.1 && make)
set (PCAP_INSTALL cd ${PCAP_ROOT}/src/curl-7.64.1 && make install)
ExternalProject_Add(curl-7.64.1
URL ${CMAKE_SOURCE_DIR}/third_party/curl/curl-7.64.1.zip
DOWNLOAD_NAME curl-7.64.1
PREFIX ${PCAP_ROOT}
CONFIGURE_COMMAND ${PCAP_CONFIGURE}
BUILD_COMMAND ${PCAP_MAKE}
INSTALL_COMMAND ${PCAP_INSTALL}
)
include_directories (${CMAKE_BINARY_DIR}/third_party/curl/include)
link_directories (${CMAKE_BINARY_DIR}/third_party/curl/lib)
openssl-1.1.1.cmake:
include(ExternalProject)
set (OPENSSL_ROOT ${CMAKE_BINARY_DIR}/third_party/openssl)
set (OPENSSL_LIB_DIR ${OPENSSL_ROOT}/lib)
set (OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT}/include)
set (OPENSSL_INSTALL_DIR ${CMAKE_BINARY_DIR}/third_party/openssl/build)
set (OPENSSL_ROOT_DIR ${CMAKE_BINARY_DIR}/third_party/openssl)
if (DEFINED CROSS)
set (OPENSSL_CONFIGURE cd ${OPENSSL_ROOT}/src/openssl &&
./Configure linux-aarch64 no-shared no-asm --prefix=${OPENSSL_INSTALL_DIR}
--cross-compile-prefix=${CROSS}- --sysroot=${CMAKE_SYSROOT})
set (OPENSSL_MAKE cd ${OPENSSL_ROOT}/src/openssl && make CC=${CROSS}-gcc AR=${CROSS}-ar RANLIB=${CROSS}-ranlib)
else()
set (OPENSSL_CONFIGURE cd ${OPENSSL_ROOT}/src/openssl && ./config no-shared no-asm --prefix=${OPENSSL_INSTALL_DIR})
set (OPENSSL_MAKE cd ${OPENSSL_ROOT}/src/openssl && make)
endif ()
set (OPENSSL_INSTALL cd ${OPENSSL_ROOT}/src/openssl && make install)
ExternalProject_Add(openssl
URL ${CMAKE_SOURCE_DIR}/third_party/openssl/openssl-OpenSSL_1_1_1-stable.zip
DOWNLOAD_NAME openssl
PREFIX ${OPENSSL_ROOT}
CONFIGURE_COMMAND ${OPENSSL_CONFIGURE}
BUILD_COMMAND ${OPENSSL_MAKE}
INSTALL_COMMAND ${OPENSSL_INSTALL}
)
include_directories (${CMAKE_BINARY_DIR}/third_party/openssl/build/include)
link_directories (${CMAKE_BINARY_DIR}/third_party/openssl/build/lib)
Как видите, curl нужен openssl, но я не могу контролировать порядок. Таким образом, на разных компьютерах возникнут ошибки, потому что openssl компилируется после curl. Итак, как я могу убедиться, что openssl скомпилирован первым?
Да, спасибо, фактическая ссылка находится в верхнем CMakeLists.txt, который я не показывал. Я думаю, что это не связано с проблемой заказа.
Хм, разве curl не связывается с openssl внутри, внутри make вызова для curl? Вот почему вы передаете -DOPENSSL_ROOT_DIR=${OPENSSL_DIR} за curlcmake. В этом случае include_directories и link_directories в основном проекте бесполезны: они вообще не влияют на ExternalProject.
Curl не может автоматически связать openssl. Это правда, что если я удалю include_directories и link_directories в openssl-1.1.1.cmake, компиляция также будет успешной.





Первый параметр ExternalProject_Add — это имя цель, которое будет создано для внешнего проекта. С помощью команды add_dependencies можно ограничить порядок сборки внешних проектов:
# Curl is built *after* the openssl have been built.
add_dependencies(curl-7.64.1 openssl)
Обратите внимание, что ваш текущий код не хватает для библиотек связывание: команда
link_directoriesтолько добавляет каталог, в котором поиск библиотеки по именам; вам все еще нуженtarget_link_librariesдля фактической ссылки. Собственно, пример подключения библиотек из внешнего проекта вы можете найти здесь: stackoverflow.com/a/29324527/3440745.