[CMake] static library from several subdirectories

Michael Wild themiwi at gmail.com
Tue Mar 16 05:24:28 EDT 2010


On 16. Mar, 2010, at 9:54 , Verweij, Arjen wrote:

> Hi,
> 
>>> Hopefully I'm misunderstanding you, since otherwise the list would
>> contain
>>> close to 4000 files.
>> 
>> Well, I don't see a real problem with this. If this makes your files too
>> long,
>> just separate the setting of these source-variables into separate files.
> 
> I would prefer to keep the source listing with the source files, so perhaps I should chain .cmake files from the level where I wish to generate mystaticlib.a. That would make maintaining the source lists easier for inadvertent users. To clarify, the average Fortran77 user (mathematician, physicist, structural engineer etc.) I know usually does not have a computer science background, so usability is a relative big issue.
> 
>>> But I took a look at Michael Wild's approach (thanks Tyler) which
>> leads me
>>> to believe there is no clean way to go about it. I suppose in the
>> spirit of
>>> his solution I could create a global list of the archives I obtain,
>> and
>>> feed them to target_link_libraries (myexecutable
>>> ${my_global_list_of_archives}) in the same scope where I call
>>> add_executable().
>> 
>> If you are creating an executable (I thought you were creating a static
>> library as end result), you can just link your executable against all
>> these
>> static libs.
> 
> I am. Well, it's complicated. We provide one big archive to link against, so the core of the program is inside the binary when they define their own routines. There is no point in making it a shared object since it is never shared. Most users will just use the binary we provide.
> 
> It just seems that cmake was set up with a different mindset, in which it is frowned upon to create a single library (static or not) composed of multiple source directories. I will try to wrap something around add_subdirectory() and have my_add_subdirectory() take care of propagation of the (127 :) source lists to the parent scope, so I can get a list for add_library(). If that fails perhaps just be satisfied with referencing all source lists explicitly from the top... Any other suggestions very welcome.
> 
> Thanks,
> Arjen


CMakeLists.txt:
###############
project(superDuper Fortran)

#- Add sources for a target
#
#  ADD_SOURCES(<target> <source1> [<source2> ...])
#
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)
    if(NOT IS_ABSOLUTE "${src}")
      get_filename_component(src "${src}" ABSOLUTE)
    endif()
    list(APPEND SRCS "${src}")
  endforeach()
  # append to global property
  set_property(GLOBAL APPEND PROPERTY "${target}_SRCS" "${SRCS}")
endfunction()

# descend into sub-directories
add_subdirectory(a)
add_subdirectory(b)

get_property(super_SRCS GLOBAL PROPERTY super_SRCS)

add_library(super STATIC ${super_SRCS})
###############

a/CMakeLists.txt:
#################
add_sources(super
  a1.f
  a2.f
  a3.f
  )
#################

b/CMakeLists.txt:
#################
add_sources(super
  b1.f
  b2.f
  )
#################



I hope this gives you an idea how you could do this in an easy-to-use way.


Michael


More information about the CMake mailing list