using find_package between 2 externalProject_add

Hello, Good morning,

I can’t find a solution to run a find_package() between 2 externalProject_add() during the “build time”. Indeed, Project2 needs Project1 both being compiled by externalProject.
But since Project2 doesn’t use cmake but nmake and make, I need to specify the path of Project1 in the arguments of nmake.
To be precise, Project2 is gdal.

Exemple code :

  set(lib_name libjpeg)
  set(git_repo https://github.com/LuaDist/libjpeg.git)
  set(git_tag 8.4.0)
  message("[INFO] beginning compilation ${lib_name}")
  set(lib_name_install ${CMAKE_CURRENT_SOURCE_DIR}/install/${BUILDNAME}/${lib_name})
  set(CMAKE_INSTALL_PREFIX ${lib_name_install})
  externalproject_add(
${lib_name}
GIT_REPOSITORY ${git_repo}
GIT_TAG ${git_tag}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${lib_name}
INSTALL_DIR ${lib_name_install}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${lib_name_install}
-DBUILD_SHARED_LIBS=OFF
  )
  set(JPEG_ROOT ${CMAKE_SOURCE_DIR}/install/${BUILDNAME}/${lib_name})

 find_package(JPEG REQUIRED)
 string(
CONCAT nmake_gdal_option "JPEG_EXTERNAL_LIB=1 "
"JPEGDIR=${JPEG_ROOT} "
"JPEG_LIB=${JPEG_LIBRARIES}"
"PNG_EXTERNAL_LIB=1"
"PNGDIR=${PNG_ROOT}"
"PNG_LIB=${PNG_LIBRARIES}"
"TIFF_INC=-I${TIFF_INCLUDE_DIR}"
"TIFF_LIB=${TIFF_LIBRARIES}"
#uncomment following line, if you have libtiff version >= 4.0 to
#enable BigTIFF support
"TIFF_OPTS=-DBIGTIFF_SUPPORT"
#"  GEOTIFF_INC =   -Ic:/warmerda/libgeotiff -Ic:/warmerda/libgeotiff/libxtiff"
#"GEOTIFF_LIB =   C:/warmerda/libgeotiff/geotiff_i.lib"

  #Uncomment for Xerces based GML and ILI support.
  "XERCES_DIR=${XERCES_ROOT}"
  "XERCES_INCLUDE=-I${XERCES_INCLUDE_DIRS} -I${XERCES_INCLUDE_DIRS}/xercesc"
  "XERCES_LIB=${XERCES_LIBRARIES}"

  #SQLite Libraries
  "SQLITE_INC=-I${SQLITE3_INCLUDE_DIR}"
  "SQLITE_LIB=${SQLITE3_LIBRARIES}"
  )

	set(lib_name gdal_git)
	set(git_repo https://github.com/OSGeo/gdal)
  ##set(git_tag v2.1.3)
	set(git_tag v2.3.0)
	message("[INFO] beginning compilation ${lib_name}")
	set(lib_name_install ${CMAKE_CURRENT_SOURCE_DIR}/install/${BUILDNAME}/${lib_name})
	set(CMAKE_INSTALL_PREFIX ${lib_name_install})
	if(WIN32)
		externalproject_add(
			${lib_name}
			#DEPENDS zlib curl geos libgeotiff libjpeg libpng jsonc iconv proj sqlite libtiff xercesc
			DEPENDS libjpeg
			GIT_REPOSITORY ${git_repo}
			GIT_TAG ${git_tag}
			SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../${lib_name}
			INSTALL_DIR ${lib_name_install}
			CONFIGURE_COMMAND ""
			BUILD_COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/../${lib_name}/gdal"
			COMMAND "dir"
			COMMAND nmake /f makefile.vc ${nmake_gdal_option}
			INSTALL_COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/../${lib_name}/gdal"
			COMMAND dir
			COMMAND nmake /f makefile.vc install GDAL_HOME="${lib_name_install}"
			COMMAND nmake /f makefile.vc devinstall GDAL_HOME="${lib_name_install}"
		)

You can use an internal API to do some replacement:

set(var "<BINARY_DIR>/some/sub/path")
_ep_replace_location_tags(proj1 var)
# var now has `<BINARY_DIR>` replaced with `proj1`'s value.

Though I would recommend instead using <INSTALL_DIR> which all projects generally share. This would allow you to do something like PROJ1_LIB=<INSTALL_DIR>/lib/proj1.lib.

I didn’t understand much…
With your method, I still couldn’t use find_package() during the build, could I?
I know the location of the libraries, but I’d rather use the ${PROJ_LIBRARIES} variable of the find_package

Yes, but you can use <INSTALL_DIR> to help find_package(proj4) find what it needs. For example, something like passing -DCMAKE_INSTALL_PREFIX:STRING=<INSTALL_DIR>.

My problem is that I can’t use the find_package at “configure” time, because an external project is not yet installed and compiled. So I have to use a find package only during the project build, after proj1 has been installed.

So your answer doesn’t seem to solve my problem.

The second external project should be doing the find_project, not the one calling ExternalProject_add.

yes but proj2 is not my project and not have cmake project. it s use nmake and make

Ok, looking closer, it looks like you’re using per-project INSTALL_DIR settings. Is there a reason for that? I think using a single install prefix for all projects would make this a lot easier.

If not, you can use _ep_replace_location_tags to expand variables for other projects to build up the information you need.

do you troll me?

I already have the solution without using a find_package between 2 ExternalProject_add, but this is verbose. I don’t want to make a mixed install directory either. I have one install directory per external project.

My initial question is how to use a find_package during the build between 2 external_project, with a find_package that refers to the first project.

Sorry about that. I don’t always go back and reread threads and I guess I lost track of what was originally being asked here.

I don’t know of any way to do what you’re asking easily other than possibly adding a CMake project in between that dumps the information out in a way that the second project slurps up during its build. Maybe you can dump out a response file (I’d use xargs, but I don’t know what Windows has like that)?

@craig.scott?

Since proj2 is not a CMake project, it can’t call find_package(). But you want the results of a find_package() call to give to it. You can’t call find_package() until build time because the thing you want it to find isn’t set up until build time. Therefore, proj2 has to either be a CMake project or you have to insert one somehow to be able to call find_package() at that point in the build stage.

Probably you will need to either insert a third project between them that writes out something that proj2 can read, or else you could try to modify proj2 to create its own local CMake project to do the same. Neither is particularly clean, but that’s hard to avoid when mixing build systems like this.

Thank you for this answer.

I tried to do this but without success.
I used an externalProject_add with just SOURCE_DIR on a local directory with a cmakelist.txt, and in this CMakelist.txt, I wanted to make an externalProject_add on proj2. But I got some strange error messages about proj2 generator problems

I have no other method than to use externalProject_Add to launch a cmakelist during the build time