Ninja Make system not accepting GENERATED command

364 Views Asked by At

I have a set of assembly files which should be compiled by a special compiler. After this it should be added to the library created by the compiler i have set in CMAKE_C_COMPILER. it was working fine with Mingw Makefile system but not working with Ninja Make.

Below is the code in cmakelists.txt

add_custom_target(
  special_asm
  COMMAND
    ${SPECIAL_ASM} ${src_file1}
    -I${INCLUDE_PATH} -o file1.o
  COMMAND
    ${SPECIAL_ASM} ${src_file2}
    -I${INCLUDE_PATH} -o file2.o
)
add_custom_target(special_asm_cmd COMMAND cmd.exe special_asm*.bat)
    
add_dependencies(special_asm_cmd special_asm)

add_library(
  mylib STATIC
  file1.o
  file2.o
  ${mylib_src})

add_dependencies(mylib  special_asm_cmd)

set_source_files_properties(
  file1.o
  file2.o
  PROPERTIES EXTERNAL_OBJECT true GENERATED true)

file1.o and file2.o are generated by different assembler. i have set the properties for these files also.

Problem 1: custom target special_asm is not directly generating the object files. It is generating a batch script. That's why i have created one more custom target called special_asm_cmd to run the batch script which will generate the object files. The Mingw make system was directly generating the object file from special_asm but Ninja is not doing like that.

Problem 2 I have set the property GENERATED true for the special generated object files. But ninja is giving the below error. But Mingw Make was able to solve the dependency and no errors

ninja: error: '<path>/spt_init.o', needed by '<path>/libmylib.a', missing and no known rule to make it
1

There are 1 best solutions below

0
On BEST ANSWER

There's no point in using GENERATED here - cmake will know it, when you tell him, how you generate the files anyway.

add_custom_command(
  # Put generated files in binary dir, where they belong
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file1.o
  # Enumerate all dependencies.
  DEPENDS
      ${src_file1}
      ${INCLUDE_PATH}/header1.h ${INCLUDE_PATH}/header2.h etc..
  COMMAND
      ${SPECIAL_ASM} ${src_file1} -I${INCLUDE_PATH} 
      -o ${CMAKE_CURRENT_BINARY_DIR}/file1.o
)
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file2.o
  DEPENDS
    ${src_file2}
    ${INCLUDE_PATH}/header1.h ${INCLUDE_PATH}/header2.h etc..
  COMMAND
    ${SPECIAL_ASM} ${src_file2}
    -I${INCLUDE_PATH}
    -o ${CMAKE_CURRENT_BINARY_DIR}/file2.o
)
add_custom_target(special_asm_cmd 
     # Enumerate the dependencies.
     DEPENDS 
         ${CMAKE_CURRENT_BINARY_DIR}/file2.o
         ${CMAKE_CURRENT_BINARY_DIR}/file1.o
     # Glob in add_custom target? Use glob with `file(GLOB ...`
     COMMAND cmd.exe special_asm*.bat
)

add_library(mylib STATIC
   ${CMAKE_CURRENT_BINARY_DIR}/file2.o
   ${CMAKE_CURRENT_BINARY_DIR}/file1.o
   ${mylib_src}
)

Cmake is a build system, specifically designed to know what comes from what. Files comes from other files plus commands. Tell cmake what files come from which commands and which source files - cmake will manage the dependencies and do all the rest like parallelizing the work and proper dependency tracking.