MantisBT - CMake
View Issue Details
0014768CMakeCMakepublic2014-02-20 15:482016-06-10 14:31
Paul Smith 
Kitware Robot 
highmajoralways
closedmoved 
AppleMac OS X10.9.1
CMake 2.8.12.2 
 
0014768: Using OBJECT libraries with Xcode causes incorrect builds
I wanted to use an OBJECT library in order to build both a static and shared library from the same set of objects, across multiple directories. This works great with Makefiles and Visual Studio but fails with Xcode: the initial build works fine but if I then change a file and re-run the build it compiles the object file but does NOT update the libraries and executables that depend on it.
CMakeLists.txt:
#----------
cmake_minimum_required(VERSION 2.8.12)
project(CMTEST CXX)

add_library(foo_OBJECTS OBJECT foo.cpp foo.h)

add_library(foo SHARED dummy.cpp $<TARGET_OBJECTS:foo_OBJECTS>)
add_dependencies(foo foo_OBJECTS)

add_executable(hello hello.cpp)
target_link_libraries(hello foo)
#----------

Then create a trivial foo.cpp, foo.h, and hello.cpp.
Run "cmake -G Xcode ."
Run "xcodebuild build -configuration RelWithDebInfo" (or use "cmake -build" if you prefer).

All builds and is fine.

Now modify foo.cpp.
Run "xcodebuild build -configuration RelWithDebInfo" again (or "cmake -build")

Note that Xcode recompiles foo.o and updates libfoo_OBJECTS.a, _BUT_ it does NOT recreate libfoo.a and it does not re-link the hello program.
I've tried this with Xcode 4.6 and Xcode 5.0. I've tried it with CMake 2.8.12.2 and also with the latest CMake 3.0.0-rc1 from Git master; same behavior in all situations.
No tags attached.
gz cmtest.tar.gz (1,030) 2014-02-21 15:01
https://public.kitware.com/Bug/file/5080/*
Issue History
2014-02-20 15:48Paul SmithNew Issue
2014-02-20 16:05Brad KingNote Added: 0035163
2014-02-21 11:59Paul SmithNote Added: 0035165
2014-02-21 12:00Paul SmithNote Added: 0035166
2014-02-21 12:09Paul SmithNote Edited: 0035165bug_revision_view_page.php?bugnote_id=35165#r1394
2014-02-21 14:33Brad KingNote Added: 0035167
2014-02-21 15:01Paul SmithFile Added: cmtest.tar.gz
2014-02-21 15:02Paul SmithNote Added: 0035168
2014-02-21 15:05Paul SmithNote Added: 0035169
2014-02-21 15:06Paul SmithNote Added: 0035170
2014-02-21 15:17Paul SmithNote Added: 0035171
2014-02-21 15:20Brad KingNote Added: 0035172
2014-02-21 17:37Paul SmithNote Added: 0035173
2016-06-10 14:29Kitware RobotNote Added: 0042492
2016-06-10 14:29Kitware RobotStatusnew => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0035163)
Brad King   
2014-02-20 16:05   
I cannot reproduce this:

$ cmake --version
cmake version 2.8.12.1

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9.1
BuildVersion: 13B42

$ xcodebuild -version
Xcode 5.0.2
Build version 5A3005

$ mkdir b && cd b
$ cmake .. -GXcode
$ xcodebuild -configuration Debug
...
Ld b/Debug/hello normal x86_64
...

$ xcodebuild -configuration Debug
(nothing builds)

$ touch ../foo.cpp

$ xcodebuild -configuration Debug
...
Ld b/Debug/hello normal x86_64
...
(0035165)
Paul Smith   
2014-02-21 11:59   
(edited on: 2014-02-21 12:09)
Wow, you're right it seems to work if you use a subdirectory!! Crazy. If I run this (mirroring what you did) it works for me:

(rm -rf b && mkdir b && cd b \
    && cmake .. -GXcode && xcodebuild -configuration Debug \
    && sleep 2 && touch ../foo.cpp && echo "----------" \
    && xcodebuild -configuration Debug 2>&1 | tee b.out | grep Ld)

and I see the "Ld" linking "hello". But, if I change it to:

(pwd=`pwd`; rm -rf ../b && mkdir ../b && cd ../b \
    && cmake "$pwd" -GXcode && xcodebuild -configuration Debug \
    && sleep 2 && touch ../foo.cpp && echo "----------" \
    && xcodebuild -configuration Debug 2>&1 | tee b.out | grep Ld)

then it fails as I describe above (no "Ld" output is seen and "hello" is not rebuilt).

(0035166)
Paul Smith   
2014-02-21 12:00   
It actually also will fail if you build in the source directory itself, not using a separate binary directory (which is actually how our real setup works, for most people).
(0035167)
Brad King   
2014-02-21 14:33   
Re 0014768:0035165: It also works correctly for me in an in-source build or with a sibling build directory outside the source.

Please attach a tarball of the exact source tree and build scripts you use to reproduce this.
(0035168)
Paul Smith   
2014-02-21 15:02   
I've attached a tarball. You unpack and cd into it and run "./runtest". I've included the output of a sample run on my system ("./runtest > run.log 2>&1"):

----------
cmake version 2.8.12.1
ProductName: Mac OS X
ProductVersion: 10.9.1
BuildVersion: 13B42
Xcode 5.0.2
Build version 5A3005
----------
-- The CXX compiler identification is Clang 5.0.0
-- Check for working CXX compiler using: Xcode
-- Check for working CXX compiler using: Xcode -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/psmith/src/cmake/b
----------
Ld /Users/psmith/src/cmake/b/Debug/libfoo.dylib normal x86_64
Ld /Users/psmith/src/cmake/b/Debug/hello normal x86_64
----------
----------

Note the empty content for the second run.
(0035169)
Paul Smith   
2014-02-21 15:05   
Here's another run from another, older system:

$ ./runtest
----------
cmake version 2.8.12.1
ProductName: Mac OS X
ProductVersion: 10.7.4
BuildVersion: 11E53
Xcode 4.6
Build version 4H127
----------
-- The CXX compiler identification is Clang 4.2.0
-- Check for working CXX compiler using: Xcode
-- Check for working CXX compiler using: Xcode -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/build/pds/b
----------
Ld /Users/build/pds/b/Debug/libfoo.dylib normal x86_64
Ld /Users/build/pds/b/Debug/hello normal x86_64
----------
----------
(0035170)
Paul Smith   
2014-02-21 15:06   
Here's a run if I change the script to use a subdirectory "b" instead of "../b":

$ ./runtest
----------
cmake version 2.8.12.1
ProductName: Mac OS X
ProductVersion: 10.9.1
BuildVersion: 13B42
Xcode 5.0.2
Build version 5A3005
----------
-- The CXX compiler identification is Clang 5.0.0
-- Check for working CXX compiler using: Xcode
-- Check for working CXX compiler using: Xcode -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/psmith/src/cmake/objtest/b
----------
Ld b/Debug/libfoo.dylib normal x86_64
Ld b/Debug/hello normal x86_64
----------
Ld b/Debug/libfoo.dylib normal x86_64
Ld b/Debug/hello normal x86_64
----------
(0035171)
Paul Smith   
2014-02-21 15:17   
FWIW, here's a run using the latest master HEAD from a day or two ago:

$ ./runtest
----------
cmake version 3.0.0-rc1

CMake suite maintained by Kitware, Inc. (kitware.com).
ProductName: Mac OS X
ProductVersion: 10.9.1
BuildVersion: 13B42
Xcode 5.0.2
Build version 5A3005
----------
-- The CXX compiler identification is AppleClang 5.0.0.5000279
-- Check for working CXX compiler using: Xcode
-- Check for working CXX compiler using: Xcode -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Warning (dev) at CMakeLists.txt:2 (project):
  Policy CMP0025 is not set: Compiler id for Apple Clang is now AppleClang.
  Run "cmake --help-policy CMP0025" for policy details. Use the cmake_policy
  command to set the policy and suppress this warning.

  Converting CXX compiler id "AppleClang" to "Clang" for compatibility.
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done
CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default. Run "cmake
  --help-policy CMP0042" for policy details. Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   foo

This warning is for project developers. Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /Users/psmith/src/cmake/b
----------
Ld /Users/psmith/src/cmake/b/Debug/libfoo.dylib normal x86_64
Ld /Users/psmith/src/cmake/b/Debug/hello normal x86_64
----------
----------
(0035172)
Brad King   
2014-02-21 15:20   
It works for me after I fix your runtest script to touch the proper file:

- && sleep 2 && touch ../foo.cpp && echo "----------" \
+ && sleep 2 && touch "$pwd/foo.cpp" && echo "----------" \
(0035173)
Paul Smith   
2014-02-21 17:37   
Bah. Hard to believe I was doing that the entire time but I can't seem to repro this with my example. Nevertheless, in my real environment this still fails:

$ touch Foo/Index.cpp
$ xcodebuild build -configuration RelWithDebInfo
...
=== BUILD TARGET Foo_OBJECTS OF PROJECT Proj WITH CONFIGURATION RelWithDebInfo ===

Check dependencies

CompileC Foo/Proj.build/RelWithDebInfo/Foo_OBJECTS.build/Objects-normal/x86_64/Index.o Foo/Index.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
...
=== BUILD TARGET Foo OF PROJECT Proj WITH CONFIGURATION RelWithDebInfo ===

Check dependencies

=== BUILD TARGET Bar OF PROJECT Proj WITH CONFIGURATION RelWithDebInfo ===

Check dependencies

so it doesn't rebuild libFoo.a (apparently decides there's nothing to do) or anything that depends on libFoo.a. However, obviously something about my translation of my complex build system into the simple example here is flawed, I'll have to figure out how to get the repro case to fail.
(0042492)
Kitware Robot   
2016-06-10 14:29   
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.