MantisBT - CMake
View Issue Details
0013282CMakeCMakepublic2012-06-08 10:412016-06-10 14:31
brett.dellegrazie 
Kitware Robot 
normalminoralways
closedmoved 
AIX 6.1 with XLCAIX6.1
CMake 2.8.8 
 
0013282: No way to explicitly specify shared library exported symbols with xlc on AIX
Hi,

The definition for the XLC compiler (modules/Compiler/XL.cmake) on AIX includes the explicit call to the CMAKE_XL_CreateExportList (IBM's CreateExportList tool) as follows:

    set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
      "${CMAKE_XL_CreateExportList} <OBJECT_DIR>/objects.exp <OBJECTS>"
      "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
      )

Note the first line of the script:
${CMAKE_XL_CreateExportList} <OBJECT_DIR>/objects.exp <OBJECTS>

This generates an export file in the objects dir which:
(a) Fails to build if there are no objects, because the file will not exist if there are no objects. Linking several static libraries together to make a shared library will cause this. In our case the static libraries are externally supplied and no source code is available (just headers). There's no way of creating a shared library version without manually generating an empty objects.exp file in the OBJECTS_DIR directory.

(b) Prevents the use of any explicit exports file in the general case

Is there any possibility of making this an optional per-target task (such as a PRE_LINK step) that can be disabled?

Its certainly easy enough to add an explicit exports file to the LINK_FLAGS on a per-target basis but there's no way of disabling the default export creation without resorting to replicating the XL.cmake file and modifying the CMake policy 0017 so cmake picks up the modified version (not maintainable long-term)
1. requires IBM xlc compiler on AIX.

case A: Fails due to missing objects.exp:

PROJECT(test_case_a)
cmake_minimum_required(VERSION 2.8)

# Libraries myA and myB are static, externally supplied with header files
# Doesn't matter if these are C or C++, the same problem occurs with both
# In this case though, assume C libraries for linking purposes
set( myA_SRCS myA.h )
set( myB_SRCS myB.h )

# Static libraries
add_library( myA STATIC IMPORTED )
set_target_properties( myA PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/myA.a )

add_library( myB STATIC IMPORTED )
set_target_properties( myB PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/myB.a )

# Create shared library variant of both
add_library( myC SHARED ${A_SRCS} ${B_SRCS} )
set_target_properties( myC PROPERTIES
    LINKER_LANGUAGE C
    PUBLIC_HEADER "${A_SRCS}" "${B_SRCS}"
    )
target_link_libraries( myC myA myB )
A workaround would be to:
1) disable policy CMP0017
2) Supply our own copy of modules/Compiler/XL.cmake
Removing the entire "if (CMAKE_XL_CreateExportList)" section
This leaves the CMAKE_${lang}_SHARED_LIBRARY_CREATE rule at the default.
3) Supply the explicit export list as a compile / link flag per-target as
appropriate
No tags attached.
Issue History
2012-06-08 10:41brett.dellegrazieNew Issue
2012-06-08 12:55Brad KingNote Added: 0029649
2012-06-08 13:02Brad KingNote Added: 0029651
2012-06-08 13:07Brad KingNote Added: 0029652
2012-06-08 13:07Brad KingStatusnew => backlog
2012-06-08 13:26brett.dellegrazieNote Added: 0029654
2012-06-20 13:27brett.dellegrazieNote Added: 0029775
2012-06-20 14:19Brad KingNote Added: 0029779
2016-06-10 14:28Kitware RobotNote Added: 0042061
2016-06-10 14:28Kitware RobotStatusbacklog => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:28Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0029649)
Brad King   
2012-06-08 12:55   
For reference, the explicit use of CreateExportList was introduced here:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d468a2c2 [^]
(0029651)
Brad King   
2012-06-08 13:02   
Another workaround may be to add this before the first project() command:

set(CMAKE_XL_CreateExportList "" CACHE INTERNAL "No explicit CreateExportList")
(0029652)
Brad King   
2012-06-08 13:07   
If an explicit export list is provided then the issue addressed by the commit linked in 0013282:0029649 does not exist anyway. Any proposed fix for this would have to replace the explicit CreateExportList call and objects.exp reference with direct use of the user-specified export list. The CMAKE_${lang}_CREATE_SHARED_LIBRARY rule variable will need <>-style placeholders for the relevant pieces that can be replaced at generate time with the right thing in each case.

Moving to backlog awaiting a concrete proposal and implementation volunteer.
(0029654)
brett.dellegrazie   
2012-06-08 13:26   
Brad: the workaround you suggested is far simpler than mine
I'll use that until a real solution is implemented - thanks for the hint!
(0029775)
brett.dellegrazie   
2012-06-20 13:27   
Brad: The workaround doesn't work for nested projects (add_subdirectory... etc)
(0029779)
Brad King   
2012-06-20 14:19   
Re 0013282:0029775: Note that 0013282:0029651 says the line has to be before the *first* project() command. More specifically it has to come before the first command that enables a language, either project() or enable_language(). Furthermore "first" must be interpreted as global to the configuration process, not just one directory.

It is a workaround, after all, so it isn't perfect. The requirements for a full fix are enumerated in 0013282:0029652.
(0042061)
Kitware Robot   
2016-06-10 14:28   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.