View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005155CMakeCMakepublic2007-06-08 22:052015-11-02 09:13
ReporterBrandon Van Every 
Assigned ToBill Hoffman 
PrioritynormalSeverityfeatureReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0005155: standard way to locate object files
DescriptionCMake 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)
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0007855)
Bill Hoffman (manager)
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 (reporter)
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 (reporter)
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 (reporter)
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 (developer)
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 (manager)
2015-11-02 09:13

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2007-08-09 14:36 Brandon Van Every Note Added: 0008390
2007-08-09 14:36 Brandon Van Every Priority low => normal
2007-08-09 14:36 Brandon Van Every Category => Test Category
2007-12-19 11:23 Joel - Schaerer Note Added: 0010001
2009-04-12 19:00 Yevgen Muntyan Note Added: 0016006
2015-04-13 13:46 Stephen Kelly Note Added: 0038503
2015-04-13 13:46 Stephen Kelly Status assigned => resolved
2015-04-13 13:46 Stephen Kelly Resolution suspended => fixed
2015-11-02 09:13 Robert Maynard Note Added: 0039767
2015-11-02 09:13 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team