[CMake] EFFECTIVE_PLATFORM_NAME not expanded in TARGET_* generator expressions on iOS

Vladimír Vondruš mosra at centrum.cz
Thu Apr 7 02:48:52 EDT 2016


Hello,

sorry for the delayed reply. The root of the problem is actually not the XCtest feature, but generator expressions. The minimal repro case is just the following CMakeLists.txt file:

    cmake_minimum_required(VERSION 3.5)

    project(IosTarget C)

    file(GENERATE
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/location.c
        CONTENT "#define LOCATION \"$<TARGET_FILE:lib>\""
        CONDITION $<CONFIG:Debug>)

    add_library(lib STATIC ${CMAKE_CURRENT_BINARY_DIR}/location.c)

Create build directory and invoke CMake like this:

    cmake .. -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -DCMAKE_OSX_ARCHITECTURES=armv7 -DCMAKE_C_COMPILER_WORKS=ON -G Xcode

(I had to put the CMAKE_C_COMPILER_WORKS there because of https://cmake.org/Bug/view.php?id=15329 -- passing the CMAKE_MACOSX_BUNDLE and CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED on command-line somehow didn't work and I didn't want to inflate the repro case with a toolchain file. By the way, why CMake can't set those properties implicitly for the compiler tests?)

Then, in the build directory a `location.c` file appears with contents similar to this:

    #define LOCATION "/path/to/the/project/build/Debug${EFFECTIVE_PLATFORM_NAME}/liblib.a"

The expected value is however this:

   #define LOCATION "/path/to/the/project/build/Debug-iphoneos/liblib.a"

Which corresponds to the location of the generated library if you run `cmake --build .`

Hope the repro case is clear enough.

Regards
mosra

______________________________________________________________
> Od: Gregor Jasny <gjasny at googlemail.com>
> Komu: "Vladimír Vondruš" <mosra at centrum.cz>, <cmake at cmake.org>
> Datum: 30.03.2016 14:15
> Předmět: Re: [CMake] EFFECTIVE_PLATFORM_NAME not expanded in TARGET_* generator expressions on iOS
>
>Hello,
>
>I fear you're one of the first users of the XCtest feature :)
>
>On 21/03/16 13:42, Vladimír Vondruš wrote:
>> Hello,
>>
>> I came across this problem when trying to use XCTest macros ( https://cmake.org/cmake/help/latest/module/FindXCTest.html ) on iOS. When compiling for OSX, ctest properly executes all test cases, but when targeting iOS or iOS simulator, all the test cases fail similarly to the following:
>>
>>      25: Test command: /Applications/Xcode.app/Contents/Developer/usr/bin/xctest "/Users/mosra/Code/corrade/build-ioss/src/Corrade/Utility/Test/Debug${EFFECTIVE_PLATFORM_NAME}/UtilityTypeTraitsTestRunner.xctest/../.."
>>      25: Environment variables:
>>      25:  DYLD_FRAMEWORK_PATH=/Users/mosra/Code/corrade/build-ioss/src/Corrade/Utility/Test/Debug${EFFECTIVE_PLATFORM_NAME}/UtilityTypeTraitsTest.framework/..
>>      25: Test timeout computed to be: 9.99988e+06
>>      25: 2016-03-21 12:41:38.799 xctest[31113:31078264] The bundle “Test” couldn’t be loaded because its executable couldn’t be located. Try reinstalling the bundle.
>>      25/28 Test #25: UtilityTypeTraitsTest ...............***Failed    0.04 sec
>>
>> As you can see, the `${EFFECTIVE_PLATFORM_NAME}` is not being expanded to `-iphonesimulator` and thus the file is not found. The problem is that the `$<TARGET_LINKER_FILE_DIR:target>` generator expression does not expand the variable. On the other hand, installation works without an issue, because the `cmake_install.cmake` scripts do additional round of variable expansion that (accidentally?) fixes this. The relevant part of the CMake source is here: https://github.com/Kitware/CMake/blob/cd569b962dbeaa7ea718021c16582cddd158df3a/Source/cmGeneratorTarget.cxx#L5063
>>
>>  From the source it looks like the generator is just putting the "${EFFECTIVE_PLATFORM_NAME}" output and hopes that someone later expands it. That's the case with install scripts (so they work), but not with generator expressions. The `TARGET_LINKER_FILE_DIR` is not the only affected, the problem is the same for all `TARGET_*` generator expressions.
>>
>> Currently I'm working around this by partially hardcoding the path, but that's far from ideal and I would like to avoid that:
>>
>>      if(CMAKE_OSX_SYSROOT MATCHES "iPhoneOS")
>>          set(platform_name "-iphoneos")
>>      elseif(CMAKE_OSX_SYSROOT MATCHES "iPhoneSimulator")
>>          set(platform_name "-iphonesimulator")
>>      endif()
>>      set(target_linker_file_dir ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>${platform_name}/${target}.xctest)
>>
>> Is there any way to fix this directly in CMake? Also the above workaround works only when targeting single SDK and not when having single generated project for both the device and the simulator.
>
>Could you please send me a minimal example and a command line how you 
>invoke CMake?
>
>Thanks,
>Gregor
>


More information about the CMake mailing list