[CMake] static library from several subdirectories
Michael Wild
themiwi at gmail.com
Fri Mar 19 09:11:28 EDT 2010
Hi
I added my comments below, inline in the code
On 19. Mar, 2010, at 13:58 , Verweij, Arjen wrote:
> Hi,
>
>> -----Original Message-----
>> 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}")
>
> OK, so I finally found some time to implement AND email the results. I tried it a little differently, then I tried Michael's approach. Both seem to fail, since at the moment I call add_library() my source file is unavailable. I hoped it would resolve the source file to a dependency through the custom command, but it doesn't and I can't get cmake to execute the conversion inline.
>
> What am I missing? I'm trying again with my simple a/liba.c and b/b/libb.c setup, but this time I start out with liba.cr and libb.cr that need to be converted to liba.c and libb.c.
>
> function(add_sources target)
> # define the <target>_SRCS properties if necessary
> get_property(prop_defined GLOBAL PROPERTY ${target}_SRCS DEFINED)
> if(NOT prop_defined)
> define_property(GLOBAL PROPERTY ${target}_SRCS
> BRIEF_DOCS "Sources for the ${target} target"
> FULL_DOCS "List of source files for the ${target} target")
> endif()
> # create list of sources (absolute paths)
> set(SRCS)
> foreach(src IN LISTS ARGN)
I know I used this syntax, but it is relatively new. Please check that it is supported by the CMake version you use...
> string (REGEX REPLACE "^(.+)\\.cr$" "\\1" BASECR ${src} )
> string (COMPARE EQUAL ${src} ${BASECR}.cr FILE_IS_C)
You're removing .cr from the file and then add it back again and compare it with the original name? that should always be TRUE, right?
> if(NOT IS_ABSOLUTE "${src}")
> get_filename_component(path_to_src "${src}" ABSOLUTE )
> get_filename_component(path_to_src "${path_to_src}" PATH )
> get_filename_component(src "${src}" ABSOLUTE)
> endif()
This is dangerous, because if src is originally absolute, path_to_src will be undefined! Change it to this:
if(NOT IS_ABSOLUTE "${src}")
get_filename_component(src "${src}" ABSOLUTE)
endif()
get_filename_component(path_to_src "${src}" PATH)
>
> add_custom_command(
> OUTPUT "${path_to_src}/${BASECR}.c"
> COMMAND cat "${path_to_src}/${BASECR}.cr" > "${path_to_src}/${BASECR}.c"
> WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
> COMMENT "Creating ${path_to_src}/${BASECR}.c"
> VERBATIM
> )
You should NEVER write to the source directory. Don't even think about it. And output-redirection doesn't work. So for your test-purposes, you could try:
file(RELATIVE_PATH rel_path_to_src "${CMAKE_CURRENT_SOURCE_DIR}" "${path_to_src}")
set(out_file "${CMAKE_CURRENT_BINARY_DIR}/${rel_path_to_src}/${BASECR}.c")
add_custom_command(
OUTPUT "${out_file}"
COMMAND ${CMAKE_COMMAND} -E copy "${src}" "${out_file}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Creating ${out_file}"
VERBATIM
)
>
> #add_custom_command (
> # OUTPUT ${path_to_src}/${BASECR}.c
> # COMMAND cat ${path_to_src}/${BASECR}.cr > ${path_to_src}/${BASECR}.c
> # DEPENDS ${path_to_src}/${BASECR}.cr
> # )
> list(APPEND SRCS "${path_to_src}/${BASECR}.c")
Of course, change this then to
list(APPEND SRCS "${out_file}")
> endforeach()
> # append to global property
> set_property(GLOBAL APPEND PROPERTY "${target}_SRCS" "${SRCS}")
> endfunction()
>
You have to call ADD_SOURCES for all your sources BEFORE you do the ADD_LIBRARY call.
HTH
Michael
More information about the CMake
mailing list