When does ExternalProject_Add build?
Asked Answered
Q

2

7

I want to build openssl and link my project against it. In my project, I have a library called net which is the part that uses openssl. So in my net\CMakeList, I added

include_directories(
    ../
  + ../../../ext/openssl/inc32/
)
add_library(net STATIC ${sources})
+ ADD_DEPENDENCIES(net openssl)

In my ext folder that is used for organizing all external library, I have a fresh unzipped openssl source code in a folder named openssl. Then I edited ext\CmakeList

message(STATUS "Configuring OpenSSL")
set(openssl_dir openssl)
if (CMAKE_CL_64)
include(ExternalProject)

set(OPENSSL_CONFIGURE perl\ Configure\ VC-WIN64A)
set(OPENSSL_MAKE  ms\\do_win64a\ &&\ nmake\ -f\ ms\\ntdll.mak)

ExternalProject_Add(openssl
    PREFIX openssl
    #-- Download Step ----------
    SOURCE_DIR ${CMAKE_SOURCE_DIR}/ext/openssl
    #--Configure step ----------
        CONFIGURE_COMMAND ${OPENSSL_CONFIGURE}
    #--Build Step ----------
    BUILD_COMMAND ${OPENSSL_MAKE}
    BUILD_IN_SOURCE 1
    #--install Step ----------
    INSTALL_COMMAND ""} 
)

endif()

When I built, the compiler complained the it can't find include files, and the openssl source code was not built at all, since there is no out32dll and inc32.

My question is: When does ExternalProject_Add actually build the project? If I make my net library depending on openssl, does it mean when I build net it would need to check and build openssl first?

Quenna answered 1/7, 2014 at 11:14 Comment(6)
This is because you need to start if with environments from vsvarsall.bat.Equiponderance
Sorry ruslo, I don't quite understand your answer. Would you mind give me more information? Thanks.Quenna
@RAM: Please stop mass editing tags into questions. Leave such mass editing to users who don't have to be reviewed. Even if you edit tags, make sure to fix all problems of the post.Haddix
@Haddix in that case who will add external-project tags to questions on using cmake's ExternalProject_Add ? No one?Retharethink
@RAM: When you encounter such questions in the normal process, then editing them is fine, but from the edits I saw it looks more as if you were searching specifically for questions where you can add the tag. Some of them are several years old. Leave that to users with more than 2k or wait until you have 2k yourself. The problem with mass edits (<2k) is that at least two other users have to review your edit with takes a lot of time.Haddix
@Retharethink And please: If you edit a question, make sure to fix all problems. In this question, for example, you should have also removed the salutation in the end, fixed the capitalization of the title and some other things (see my edit).Haddix
E
2

Install missed

First of all I think you missed an install step. See documentation:

nmake -f "ms\ntdll.mak" install

So simplified version of ExternalProject_Add is:

ExternalProject_Add(
    OpenSSL
    URL https://github.com/openssl/openssl/archive/OpenSSL_1_0_1h.tar.gz
    CONFIGURE_COMMAND perl Configure VC-WIN64A "--prefix=${CMAKE_INSTALL_PREFIX}"
    BUILD_COMMAND "ms\\do_win64a.bat"
    COMMAND nmake -f "ms\\ntdll.mak"
    BUILD_IN_SOURCE 1
    INSTALL_COMMAND nmake -f "ms\\ntdll.mak" install
)

Find OpenSSL

Second, if you want to find openssl libraries and headers, you need to use find_package(OpenSSL) command:

find_package(OpenSSL REQUIRED)
message("Libs: ${OPENSSL_LIBRARIES}")
message("Includes: ${OPENSSL_INCLUDE_DIR}")

Builds

Now, if you put all this commands together in one project configure step will fail :) Because it's not how ExternalProject designed. Superbuild that made by few or one ExternalProject_Add commands must be configured first, then build step will install the libraries from external archives. This will conflict with your project, because openssl libraries can't be found - they are not installed by superbuild yet.

Fix

Split cmake code. Run superbuild first (i.e. download and install openssl):

> cmake -Hsuperbuild -B_builds\superbuild "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
# note, no ext\install directory yet
> cmake --build _builds\superbuild
# install done, libraries can be found in ext\install

Then build your project, note that the libraries found on configure step:

> cmake -Huse -B_builds\use "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
-- Found OpenSSL: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib (found version "1.0.1h")
Libs: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib
Includes: .../ext/install/include
> cmake --build _builds\use
# OK

Experimental

I have an experimental project that wrap all of this noise in one command (Windows tested on Visual Studio 2013):

hunter_add_package(OpenSSL)
find_package(OpenSSL REQUIRED)
Equiponderance answered 3/7, 2014 at 17:27 Comment(0)
H
5

ExternalProject use add_custom_target internally to create project and according to its document

By default nothing depends on the custom target. Use ADD_DEPENDENCIES to add dependencies to or from other targets.

So if no project depend on it, it will not build by default.

  1. When this ExternalProject_Add actually builds the project?

    At build time(not at cmake time).

  2. If I make my net library depends on openssl, does it mean when I build net it would need to check and build openssl first?

    No. Since you make the dependency, cmake will handle it and openssl will be build before your library.

PS: There's still a lot of work to do. Because cmake doesn't know where the openssl result is, your project may run into link error. Here is a good example from the answer of "What is the best way to build boost with cmake".It use add_library with IMPORTED GLOBAL and set_target_properties with IMPORTED_LOCATION_* to solve the problem

Hebner answered 2/7, 2014 at 10:58 Comment(1)
I will worry about link error later. I think that line with ADD_DEPENDENCIES makes my net project depends on openssl, so I am expecting when I build my projects, cmake would automatically check and build openssl before my net project. If I manually build OpenSSL using those commands, there would be 2 (maybe more) folders generated after build, inc32 and out32dll.Quenna
E
2

Install missed

First of all I think you missed an install step. See documentation:

nmake -f "ms\ntdll.mak" install

So simplified version of ExternalProject_Add is:

ExternalProject_Add(
    OpenSSL
    URL https://github.com/openssl/openssl/archive/OpenSSL_1_0_1h.tar.gz
    CONFIGURE_COMMAND perl Configure VC-WIN64A "--prefix=${CMAKE_INSTALL_PREFIX}"
    BUILD_COMMAND "ms\\do_win64a.bat"
    COMMAND nmake -f "ms\\ntdll.mak"
    BUILD_IN_SOURCE 1
    INSTALL_COMMAND nmake -f "ms\\ntdll.mak" install
)

Find OpenSSL

Second, if you want to find openssl libraries and headers, you need to use find_package(OpenSSL) command:

find_package(OpenSSL REQUIRED)
message("Libs: ${OPENSSL_LIBRARIES}")
message("Includes: ${OPENSSL_INCLUDE_DIR}")

Builds

Now, if you put all this commands together in one project configure step will fail :) Because it's not how ExternalProject designed. Superbuild that made by few or one ExternalProject_Add commands must be configured first, then build step will install the libraries from external archives. This will conflict with your project, because openssl libraries can't be found - they are not installed by superbuild yet.

Fix

Split cmake code. Run superbuild first (i.e. download and install openssl):

> cmake -Hsuperbuild -B_builds\superbuild "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
# note, no ext\install directory yet
> cmake --build _builds\superbuild
# install done, libraries can be found in ext\install

Then build your project, note that the libraries found on configure step:

> cmake -Huse -B_builds\use "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
-- Found OpenSSL: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib (found version "1.0.1h")
Libs: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib
Includes: .../ext/install/include
> cmake --build _builds\use
# OK

Experimental

I have an experimental project that wrap all of this noise in one command (Windows tested on Visual Studio 2013):

hunter_add_package(OpenSSL)
find_package(OpenSSL REQUIRED)
Equiponderance answered 3/7, 2014 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.