MantisBT - CMake
View Issue Details
0005155CMakeCMakepublic2007-06-08 22:052015-11-02 09:13
Brandon Van Every 
Bill Hoffman 
normalfeaturealways
closedfixed 
 
 
0005155: standard way to locate object files
CMake doesn't currently support so-called "convenience libraries." The purpose of a convenience library is to reduce the number of link flags that a user has to provide. One way to fake it, is to reuse the object files of a previously built library, rather than the library itself.

Reusing object files would be easier if there was a standard way to determine their location. Currently I use the following non-standard way to determine their location. It has been proven to work in a production setting on multiple platfomrs for several months now. However, if CMake changes its internal implementation, it will break. Hence the desire for a standard mechanism.

Lots of people do ask for some kind of "convenience library" capability, and there are probably other uses for knowing where the object files are located.

# The shared libraries
# libchicken, libuchicken, libchicken-gui, libuchicken-gui
# and the static libraries
# libchicken-boot, libchicken-static, libuchicken-static, libchicken-gui-static, libuchicken-gui-static
# all need the static PCRE library.
#
# We can easily include a static PCRE library in shared Chicken library. Unfortunately, we
# cannot include a static PCRE library in a *static* Chicken library. "ar" is the underlying library
# tool on several platforms, and it can't put static libraries in static libraries.
#
# One workaround is to compile the PCRE sources straight into the static Chicken libraries.
# This is relatively simple to implement, and has the advantage of depending on 100% well defined
# CMake interfaces. But, it leads to compilation redundancy in 5 static libraries.
#
# Another workaround is to deduce where the PCRE object files live, and include the object files
# directly into the static Chicken libraries. With this approach we can eliminate the compilation
# redundancy. However, it relies on some assumptions about what directories CMake uses,
# and these directories could change in the future. For now though, it is the most efficient route.
#
# Once this code is proven good, I'll make a CMake feature request, for a standard way to get the
# object directories and possibly the objects. This would take the black magic out of the approach.
#
# libchicken-boot is consumed only by chicken-boot. Thus it's no big deal to manually link
# libchicken-boot as a dependency. We build an appropriate library in the /pcre subdirectory for
# this purpose. This also produces all of the object files we want.

ADD_SUBDIRECTORY(pcre)


# Then we use the following voodoo to reuse the objects.
#
# CMake generators are currently of 2 types: those which build single configurations, and those
# which build multiple configurations. These 2 types use 2 different directory structures for where
# they put their object files. The currently recommended way to deduce which type of generator
# we're using, is to see if CMAKE_CONFIGURATION_TYPES is empty or not. If it's empty, then it's
# single configuration. If it's non-empty, then it's multiple configuration, and contains a list of all
# the configurations available. We're not interested in that list, only whether it's empty or non-empty.

IF(CMAKE_CONFIGURATION_TYPES)
  # We have a multiple configuration generator. Use this directory structure.
  #
  # Note that CMAKE_BUILD_TYPE has no value when Visual Studio .sln files are generated.
  # This is because on MSVC, no build type is actually selected at generation time. The MSVC
  # user typically selects her build type after opening the .sln file. CMAKE_CFG_INTDIR expands
  # to a Visual Studio macro that will contain the right value, once Visual Studio is opened and
  # a build type is selected.
  SET(PCRE_FOR_STATIC_OBJ_DIR
    ${CMAKE_BINARY_DIR}/pcre/libpcre-for-static.dir/${CMAKE_CFG_INTDIR})
ELSE(CMAKE_CONFIGURATION_TYPES)
  # We have a single configuration generator. Use this directory structure:
  SET(PCRE_FOR_STATIC_OBJ_DIR
    ${CMAKE_BINARY_DIR}/pcre${CMAKE_FILES_DIRECTORY}/libpcre-for-static.dir)
ENDIF(CMAKE_CONFIGURATION_TYPES)

# Now we know what directory the objects live in. Construct the actual list of objects:

SET(PCRE_FOR_STATIC_OBJS ${PCRE_ROOTS})
ADD_SUFFIX(PCRE_FOR_STATIC_OBJS ${CMAKE_C_OUTPUT_EXTENSION})
ADD_PREFIX(${PCRE_FOR_STATIC_OBJ_DIR}/ PCRE_FOR_STATIC_OBJS)
No tags attached.
Issue History
2007-08-09 14:36Brandon Van EveryNote Added: 0008390
2007-08-09 14:36Brandon Van EveryPrioritylow => normal
2007-08-09 14:36Brandon Van EveryCategory => Test Category
2007-12-19 11:23Joel - SchaererNote Added: 0010001
2009-04-12 19:00Yevgen MuntyanNote Added: 0016006
2015-04-13 13:46Stephen KellyNote Added: 0038503
2015-04-13 13:46Stephen KellyStatusassigned => resolved
2015-04-13 13:46Stephen KellyResolutionsuspended => fixed
2015-11-02 09:13Robert MaynardNote Added: 0039767
2015-11-02 09:13Robert MaynardStatusresolved => closed

Notes
(0007855)
Bill Hoffman   
2007-06-11 09:49   
This is a really difficult technical problem. Xcode and visual studio are the main trouble. With makefiles it can be done in CVS CMake. I thought I was close to having this working, but at the end of the day could not get it to work with all generators. There is even a test created:
/Tests/ConvLibrary
It is currently commented out because it does not work every where. In CVS CMake you can do this:
get_target_property(OBJECT_FILES foo OBJECT_FILES)
However, there are issues. If anyone wants to try and create a patch, that test would be a good place to start.
(0008390)
Brandon Van Every   
2007-08-09 14:36   
Upping priority because people ask about reusing objects fairly frequently. Typically they want the functionality of "convenience libraries."
(0010001)
Joel - Schaerer   
2007-12-19 11:23   
This issue is related:

http://www.cmake.org/pipermail/cmake/2005-September/007271.html [^]

This is a real problem, and the static library hack doesn't work well
if you have many executables that don't all use all the object files :
changing one single file will cause a massive relink which is very slow.

There should at lease be a way to turn the executable.dir "feature" off. We are currently considering switching back to manually generated makefiles since we are not happy with the idea of compiling everything three to ten times.
(0016006)
Yevgen Muntyan   
2009-04-12 19:00   
Anybody knows a workaround at least? Static libraries won't do if you have them depend on each other, like libfoo using libblah and vice versa, so that you would need to pass "libfoo.a libblah.a libfoo.a" to the linker. I don't know if it's possible in cmake, but it's just not feasible when you have more libraries to link together. Libtool convenience libraries feature is really really useful and needed, and it's so much more than static libraries (they also remember linker flags, feature which isn't addressed in this bug report at all).
(0038503)
Stephen Kelly   
2015-04-13 13:46   
CMake now provides OBJECT libraries:

 http://www.cmake.org/cmake/help/v3.2/manual/cmake-buildsystem.7.html#object-libraries [^]

If you have further use cases not satisfied by that, please file a separate bug.
(0039767)
Robert Maynard   
2015-11-02 09:13   
Closing resolved issues that have not been updated in more than 4 months.