[CMake] static library from several subdirectories

Michael Wild themiwi at gmail.com
Wed Mar 17 08:33:24 EDT 2010


On 17. Mar, 2010, at 13:01 , Verweij, Arjen wrote:

> Hi,
> 
>> From: Michael Wild [mailto:themiwi at gmail.com]
> 
>> I'd recommend to change the add_sources function to do all the
>> preprocessing and then only add the products (.f, .f90, .c etc.) files
>> to the list. You can do the preprocessing like this (of course, you'll
>> have to change things for your setup, perhaps even do different things
>> depending on filename extension etc.)
>> 
>> find_program(FPP_EXECUTABLE fpp)
>> if(NOT FPP_EXECUTABLE)
>> message(SEND_ERROR "Failed to find fpp")
>> endif()
>> 
>> set(SRCS)
>> foreach(src IN LISTS ARGN)
>> get_filename_component(abs_src "${src}" ABSOLUTE)
>> file(RELATIVE_PATH rel_src "${CMAKE_CURRENT_SOURCE_DIR}" "${abs_src}")
>> set(pre "${CMAKE_CURRENT_BINARY_DIR}/${rel_src}")
>> add_custom_command(OUTPUT "${pre}"
>>   COMMAND ${FPP_EXECUTABLE} "${abs_src}" -o "${pre}"
>>   WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
>>   COMMENT "Creating ${pre}"
>>   VERBATIM
>>   )
>> list(APPEND SRCS "${pre}")
>> endforeach()
>> set_property(GLOBAL APPEND PROPERTY "${target}_SRCS" "${SRCS}")
> 
> The flow currently is:
> # build mybiglib.a
> 
> - loop over a file list retrieved from a leaf cmake file
> - determine the file type (FORTRAN FORTRAN90 C C++ header file etc etc)
> - add_custom_command that creates a DEPENDS of the required OUTPUT source file based on its source*r file based on a COMMAND.
> - add the OUTPUT to a filelist_m or filelist_h if is is a header file
> - setup a FORTRAN module directory in ${CMAKE_BINARY_DIR}
> - add a dependency between the header files and the current dir for preprocessing
> - ADD_SOURCES( ${BIG_LIB} ${filelist_m} ) # Michael's code
> - process some out of tree include directories # this requires touching up, but seems to work in the old setup
> - add them as a dependency for biglib
> - add a dependency between biglib and the current dir preprocessing target
> - call include_directories() for every out of tree include directory
> 
> The calls that are failing are:
> -     add_dependencies (${BIG_LIB} ${P1TARGET}_preprocessing) (2x)
> -     add_dependencies (${BIG_LIB} ${CUR_DIR}_preprocessing)
> 
> The context is:
> 
>    # use one mod dir per CMAKE_BINARY_DIR instead of a single mod dir per CMAKE_CURRENT_BINARY_DIR
>    # FIXME there may be a problem with duplicate names for the modules -- check with development
>    set (CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/mod")
>    add_custom_target (${CUR_DIR}_preprocessing DEPENDS ${FILE_LIST_H})
>    ADD_SOURCES( ${BIG_LIB} ${FILE_LIST_M} )
>    message ( STATUS filelist_m=${FILE_LIST_M} )
>    # refactor later
>    foreach (IDIR ${INCLUDE_DIRECTORIES_PREPRO})
>    include_directories (${CMAKE_BINARY_DIR}/${IDIR})
>    string (REPLACE / _ PTARGET ${IDIR})
>    string (REGEX REPLACE "^(.+)_$" "\\1" P1TARGET ${PTARGET})
> 
>    add_dependencies (${BIG_LIB} ${P1TARGET}_preprocessing) #fails now
>    endforeach (IDIR)
>    add_dependencies (${BIG_LIB} ${CUR_DIR}_preprocessing) #fails now
> 
>    foreach (IDIR ${INCLUDE_DIRECTORIES})
>    include_directories (${IDIR})
>    endforeach (IDIR)
> 
> 
> I'll be looking into this some more at the end of the day.
> 
> Regards,
> Arjen

I think the problem is that the ${BIG_LIB} target does not exist when you call ADD_DEPENDENCIES. Probably you should also collect all the custom targets into a global property and then after the ADD_LIBRARY(${BIG_LIB} ...) do the ADD_DEPENDENCIES call.

Michael

PS: Sorry about my last message which was a bit messy (missing dependency stuff, wrong output name etc). My only apology is that it was still early in the morning ;-)



More information about the CMake mailing list