[CMake] Merging static libraries

Emmanuel Blot eblotml at free.fr
Tue Oct 14 18:29:07 EDT 2008


> Do you actually have to build them as separate static libs or could  
> you just
> build one big static lib ?

No I really can't do otherwise (for various reasons)

> Please post the code which didn't work for you.

So basically, the project tree structure is as follow:

sdk/
    CMakeLists.txt  (A)
    drivers/
        CMakeLists.txt  (B)
        driver1/
               CMakeLists.txt (C)
                include/
                src/
        driver2
               CMakeLists.txt
                include/
                src/
        ....
    userlibs/
       userlib1
       userlib2
       ....

(A) contains all the global rules for the projects (compiler defs,  
macros, etc.
(B) simply contains a list of the subproject to build, and the call to  
the macro that merges (driver1, driver2, ...) into the "global" library
(C) contains the rules to build a single component (ADD_LIBRARY...)


-------------------------------------

(C) typical:

ADD_LIBRARY (ns_crc
              src/ns_crc.c)


-------------------------------------

(B):

# the "global" static lib to build
PROJECT (drivers)

# subproject to build
FILE (GLOB components RELATIVE ${neosys_SOURCE_DIR} ns_*)

# build all subprojects
FOREACH (project ${components})
   ADD_SUBDIRECTORY (${project} ${project})
ENDFOREACH (project)

# install libraries and public header files
create_package (drivers ${CMAKE_CURRENT_BINARY_DIR} ${components})


-------------------------------------

(A) is quite big, but the relevant macro is:


MACRO (create_package)
   SET (args ${ARGV})
   # first arg is the "global" lib name,
   # second arg is the "global" lib binary directory
   # remaining args are the subprojects
   LIST (GET args 0 plprj)
   LIST (GET args 1 pldir)
   LIST (REMOVE_AT args 0 1)
   # if there is no input library, do not try to build a package
   SET (wkdir ${pldir}/tmp)
   FILE (MAKE_DIRECTORY ${wkdir})
     ADD_CUSTOM_TARGET (${plprj}-collect ALL
                        COMMAND rm -f *
                        COMMAND find .. -name "*.a" -exec ${xar} -x {}  
\;
                        # this directive seems to work for all but one  
subproject, which is build AFTER this custom target is built
                        DEPENDS ${args}
                        VERBATIM
                        WORKING_DIRECTORY ${wkdir}
                        COMMENT "Collecting components for ${plprj}.a")
     ADD_CUSTOM_TARGET (${plprj}-archive ALL
                        COMMAND ${xar} -r -c ../lib${plprj}.a *
                        COMMAND rm -f *
                        WORKING_DIRECTORY ${wkdir}
                        COMMENT "Assembling package ${plprj}.a")
     ADD_DEPENDENCIES(${plprj}-archive ${plprj}-collect)
   INSTALL (FILES ${pldir}/lib${plprj}.a DESTINATION $ 
{SDK_INSTALL_DIR}/lib)
ENDMACRO (create_package)


Thanks,
Emmanuel



More information about the CMake mailing list