[CMake] Static Modules

Michael Wild themiwi at gmail.com
Thu Mar 11 03:35:19 EST 2010


On 11. Mar, 2010, at 8:56 , Markus Raab wrote:

> Hi!
> 
> Ryan Pavlik wrote:
>> get_target_properties() with the property SOURCES
>> then for each value you get back there, do a
>> get_source_file_properties() for LOCATION
>> and add all such locations to a new list, then create a target with that
>> source list.
> 
> Thank you for your answer.
> 
> The method you described: Do I have to apply it to each module?
> The target is then the static library where the modules are included?
> 
> Do you have a running example? This would help me a lot! I am still puzzling
> what "Source names" are?
> 
> http://www.cmake.org/cmake/help/cmake2.6docs.html#prop_tgt:SOURCES
> Says nothing about it.
> 
> best regards
> Markus

IMHO it would be simpler and safer to have a function which collects all the file names, adds them to a global property and then allows you to compile a static library from that. E.g (completely untested):

#- Wrapper of add_library to allow for static modules
#
#  MY_ADD_LIBRARY(<name> [STATIC|SHARED|MODULE]
#                 [EXCLUDE_FROM_ALL]
#                 [STATIC_NAME <static_name>]
#                 <source1> ... <sourceN>)
#
# If STATIC_NAME <static_name> is given, the sources will be appended to
# the global property MY_STATIC_MODULES_<static_name>_SOURCES which can
# then be used with MY_ADD_STATIC_MODULE() to create a static module from
# all of the sources.
function(my_add_library name)
  # parse arguments
  set(next_is_static_name FALSE)
  set(static_name)
  set(srcs)
  set(lib_type)
  set(exclude_from_all)
  foreach(arg IN LISTS ARGN)
    if(arg STREQUAL STATIC_NAME)
      set(next_is_static_name TRUE)
    elseif(arg MATCHES "STATIC|SHARED|MODULE")
      set(lib_type ${arg})
    elseif(arg STREQUAL EXCLUDE_FROM_ALL)
      set(exclude_from_all ${arg})
    elseif(next_is_static_name)
      set(static_name ${arg})
    else()
      # ensure that sources are absolute paths
      if(NOT IS_ABSOLUTE "${arg}")
        get_filename_component(arg "${arg}" ABSOLUTE)
      endif()
      list(APPEND srcs "${arg}")
    endif()
  endforeach()
  # require at least one source file
  if(NOT srcs)
    message(SEND_ERROR "At least one source file required")
  endif()
  # if we have a STATIC_NAME, append the sources to the global property
  if(static_name)
    set(prop_name MY_STATIC_MODULES_${static_name}_SOURCES)
    get_property(prop_defined GLOBAL PROPERTY ${prop_name} DEFINED)
    if(NOT prop_defined)
      define_property(GLOBAL PROPERTY ${prop_name}
          BRIEF_DOCS "Sources for static module ${static_name}"
          FULL_DOCS "Source files to be compiled into the static module ${static_name}")
    endif()
    set_property(GLOBAL APPEND PROPERTY ${prop_name} ${srcs})
  endif()
  # finally, create the normal library
  add_library(${name} ${lib_type} ${exclude_from_all} ${srcs})
endfunction()
    
#- Create a static library from sources collected by MY_ADD_LIBRARY
#
#  MY_ADD_STATIC_MODULE(<name>)
#
# Compiles a static library <name> from the sources defined in
# MY_STATIC_MODULES_<name>_SOURCES by MY_ADD_LIBRARY(). This
# function must be called after all calls to MY_ADD_LIBRARY()
# contributing sources to this static module.
function(my_add_static_module name)
  get_property(srcs GLOBAL PROPERTY
      MY_STATIC_MODULES_${name}_SOURCES)
  if(not SRCS)
    message(SEND_ERROR "No sources defined for static module ${name}")
  endif()
  add_library(${name} STATIC ${srcs})
endfunction()


HTH

Michael


More information about the CMake mailing list