[CMake] Download and Build external dependencies

Michael Hertling mhertling at online.de
Sun Jul 3 04:29:25 EDT 2011


On 07/01/2011 01:48 PM, Martin Köhler wrote:
> Hi,
> I'm currently trying to  write a cmake script, which downloads some
> source code and compile it during the configuration step. In my case
> this I want to try it with BLAS from netlib.org because it represents
> the problem in a good way ( and I need it for BLAS and similar
> structured source code). That background is: If a necessary library
> isn't found on the system, I will download the reference version and
> compile it.
> 
> Therefore I wrote the following code:
> 
> # Download and Build reference BLAS
> MESSAGE(STATUS " --> BUILD BLAS")
> file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/build)
> SET (BLAS_DIR ${CMAKE_BINARY_DIR}/build/BLAS)
> MESSAGE(STATUS " --> DOWNLOAD BLAS")
> file(DOWNLOAD http://www.netlib.org/blas/blas.tgz
> ${CMAKE_BINARY_DIR}/build/blas.tgz SHOW_PROGRESS)
> MESSAGE(STATUS " --> EXTRACT BLAS")
> execute_process(COMMAND tar xzf blas.tgz WORKING_DIRECTORY
> ${CMAKE_BINARY_DIR}/build/ )
> MESSAGE(STATUS " --> COMPILE BLAS: "  "${CMAKE_Fortran_COMPILER}
> ${CMAKE_FORTRAN_FLAGS} -c -O2 *.f  in  ${CMAKE_BINARY_DIR}/build/BLAS" )
> execute_process(COMMAND "${CMAKE_Fortran_COMPILER}
> ${CMAKE_FORTRAN_FLAGS} -c -O2 *.f" WORKING_DIRECTORY
> ${CMAKE_BINARY_DIR}/build/BLAS/ )
> execute_process(COMMAND ar cr libblas.a *.f WORKING_DIRECTORY
> ${CMAKE_BINARY_DIR}/build/BLAS/)
> 
> 
> This works until the archive is extracted. The compile step seems to be
> not executed. The ar step claims that there is not such file *.f
> 
> 
> How can I get this running?
> 
> 
> best regards, Martin

EXECUTE_PROCESS(COMMAND "${CMAKE_Fortran_COMPILER} ... -c *.f" ...) does
not work because the whole string "${CMAKE_Fortran_COMPILER} ... -c *.f"
is interpreted as the command - which will fail, of course.

EXECUTE_PROCESS(COMMAND ${CMAKE_Fortran_COMPILER} ... -c *.f ...) would
not work because *.f isn't expanded to the list of source files - there
is no shell involved.

You might capture the source files via FILE(GLOB ...) before:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(EXECUTE C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/f1.c "void f1(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/f2.c "void f2(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/f3.c "void f3(void){}\n")
FILE(GLOB SRCS "${CMAKE_BINARY_DIR}/*.c")
EXECUTE_PROCESS(
    COMMAND ${CMAKE_C_COMPILER} -c ${SRCS}
    RESULT_VARIABLE RESULT)
MESSAGE("RESULT: ${RESULT}")

However, you should absolutely use the ExternalProject module
for this purpose as it has been recommended in the meantime.

Regards,

Michael


More information about the CMake mailing list