0

I'm using cmake to generate Makefile for a project. In the top CMakeLists.txt, I need to include some sub modules. So it is like:

include(cmake/Modules/pcre-8.40.cmake)
include(cmake/Modules/curl-7.64.1.cmake)
include(cmake/Modules/openssl-1.1.1.cmake)

The curl-7.64.1.cmake is like:


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)

As you can see, the curl needs openssl, but I can not control the order. So in different computers, errors would happen because the openssl is compiled after curl. So how can I make sure the openssl is compiled first?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Newman
  • 5
  • 3
  • Note, that your current code **lacks** for libraries **linking**: the command `link_directories` only adds a directory where to *search* the libraries by names; you still need `target_link_libraries` for actual linking. Actually, you may find an example of linking libraries from the external project here: https://stackoverflow.com/a/29324527/3440745. – Tsyvarev Apr 23 '19 at 11:37
  • Yes, thank you, the actual linking is in the top CMakeLists.txt that I did't show. I think it is not related to the order problem. – Newman Apr 23 '19 at 14:19
  • Hm, isn't `curl` links with `openssl` internally, inside `make` invocation for `curl`? This is why you pass `-DOPENSSL_ROOT_DIR=${OPENSSL_DIR}` for `curl`'s `cmake`. In that case `include_directories` and `link_directories` in the main project are useless: they do not affect on the ExternalProject at all. – Tsyvarev Apr 23 '19 at 14:37
  • Curl can't link openssl automatically. It is true that if I delete the include_directories and link_directories in openssl-1.1.1.cmake, the compile is also succeful. – Newman Apr 24 '19 at 01:57

1 Answers1

1

The first parameter to ExternalProject_Add is a name of the target, which will be created for the External Project. Using add_dependencies command one may restrict the order in which external projects will be built:

# Curl is built *after* the openssl have been built.
add_dependencies(curl-7.64.1 openssl)
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153