CMake define new target by string processing existing $<TARGET

I"m trying to modernize an older CMake script that essentially does the following to generate a libtool file:

get_target_property(target_location ${target} LOCATION)
get_filename_component(target_we ${target_location} NAME_WE)
get_target_property(target_deps ${target} LT_DEPENDENCY_LIBS)
# ...
# Get a bunch more properties...
# ...
set(la_target ${PROJECT_BINARY_DIR}/${target_we}.la)
# ...
# Do a bunch of file(WRITE...) file(APPEND...) etc
# ...
install(FILES ${la_target} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)

You cannot get the LOCATION property from a target in modern cmake, and I can't figure out how to do get_filename_component() on a $ generator.

Using the generator in an add_custom_command() COMMAND statement only allows one line, so I can't set variables to do all the necessary get_target_property()/file(WRITE...) processing.

Alternatively I can add a COMMAND cmake -P script.cmake to run a script which can do all the string processing but can't define or reference targets, so I appear to be stuck.

EDIT: I'm using the Makefile generator, on macOS, the target in question is a shared library that's generated in the same project.

EDIT2: The error is:

The LOCATION property may not be read from target "mytarget".  
Use the target name directly with add_custom_command, or use 
the generator expression $<TARGET_FILE>, as appropriate.

You can to it like this:

  • first use file command to expand generator expressions and render a level-2 template
  • ... which is going to be rendered at build time by configure_file
  • Here is a sample project:

    cmake_minimum_required(VERSION 3.10)
    
    project(location-test VERSION 0.0.1 LANGUAGES CXX)
    
    add_executable(foo foo.cc)
    
    file(GENERATE OUTPUT blah.la.in INPUT blah.la.in.in)
    
    configure_file(render-variables.cmake.in render-variables.cmake @ONLY)
    
    add_custom_command(
        OUTPUT "${PROJECT_BINARY_DIR}/blah.la"
        COMMAND "${CMAKE_COMMAND}"
            -DPROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}"
            -DPROJECT_NAME="${PROJECT_NAME}"
            -DPROJECT_VERSION="${PROJECT_VERSION}"
            -P "${PROJECT_BINARY_DIR}/render-variables.cmake"
        MAIN_DEPENDENCY "${PROJECT_BINARY_DIR}/blah.la.in"
        DEPENDS "${PROJECT_BINARY_DIR}/render-variables.cmake"
    )
    
    add_custom_target(
        make-la-la-la ALL
        DEPENDS "${PROJECT_BINARY_DIR}/blah.la"
    )
    

    blah.la.in.in (2-levels of tempaltes %):

    # This file going to be rendered by the following pipeline:
    # - at CMake execution time it'll expand all generator expressions 
    # (e.g. $<TARGET_FILE:foo>)
    # - at build time, the `render-variables.cmake` script will substitute 
    # CMake variables (like @PROJECT_NAME@ or @PROJECT_VERSION@)
    

    write the template for your real .la file... render-variables.cmake.in is trivial as :

    configure_file("${PROJECT_BINARY_DIR}/blah.la.in" "${PROJECT_BINARY_DIR}/blah.la" @ONLY)
    

    And finally a dummy C++ file foo.cc :

    #include <iostream>
    
    int main()
    {
        std::cout << "Hello Africa!n";
    }
    

    Build it!

    localtion-sample$ mkdir build/
    localtion-sample$ cd build/
    localtion-sample/build$ cmake ..
    -- The CXX compiler identification is GNU 5.4.0
    -- Check for working CXX compiler: /usr/x86_64-pc-linux-gnu/gcc-bin/5.4.0/c++ -- works
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /tmp/localtion-sample/build
    
    localtion-sample/build$ make 
    Scanning dependencies of target foo
    [ 33%] Building CXX object CMakeFiles/foo.dir/foo.cc.o
    [ 66%] Linking CXX executable foo
    [ 66%] Built target foo
    Scanning dependencies of target make-la-la-la
    [100%] Generating blah.la
    [100%] Built target make-la-la-la
    
    localtion-sample/build$ ll
    total 52K
    drwxr-xr-x 6 zaufi zaufi  320 Feb  9 22:35 CMakeFiles/
    -rw-r--r-- 1 zaufi zaufi  287 Feb  9 22:35 blah.la
    -rw-r--r-- 1 zaufi zaufi  300 Feb  9 22:35 blah.la.in
    -rw-r--r-- 1 zaufi zaufi  11K Feb  9 22:35 CMakeCache.txt
    -rw-r--r-- 1 zaufi zaufi 1.5K Feb  9 22:35 cmake_install.cmake
    -rwxr-xr-x 1 zaufi zaufi  14K Feb  9 22:35 foo
    -rw-r--r-- 1 zaufi zaufi 5.0K Feb  9 22:35 Makefile
    -rw-r--r-- 1 zaufi zaufi   89 Feb  9 22:35 render-variables.cmake
    
    localtion-sample/build$ cat blah.la
    # This file going to be rendered by the following pipeline:
    # - at CMake execution time it'll expand all generator expressions
    # (e.g. /tmp/localtion-sample/build/foo)
    # - at build time, the `render-variables.cmake` script will substitute
    # CMake variables (like location-test or 0.0.1)
    
    链接地址: http://www.djcxy.com/p/31886.html

    上一篇: 通过属性值排序JavaScript对象

    下一篇: CMake通过字符串处理现有的$ <TARGET来定义新的目标