mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.64k stars 1.64k forks source link

CMake subproject doesn't support compiler flags and defines for individual files in the target #13846

Open marecki315 opened 3 weeks ago

marecki315 commented 3 weeks ago

Problem

Preparing a build.ninja for a CMake subproject following steps are done:

  1. cmake command is run in the subproject with -G Ninja option to generate build.ninja file
  2. build.ninja file is interpreted by Meson to prepare a Meson AST file
  3. AST file is used in a process of generating a full build.ninja file for the main project and subprojects

In CMake individual files (or sets of files) inside one target can have their own COMPILE_DEFINITIONS or COMPILE_FLAGS set using something like:

set_property( SOURCE ${SET_OF_SRC_FILES} APPEND PROPERTY COMPILE_DEFINITIONS USE_DEFINITION )
set_property( SOURCE ${SET_OF_SRC_FILES} APPEND PROPERTY COMPILE_FLAGS USE_FLAG )

In step 1. the definitions and files are respected but in step 2. when the build.ninja file is interpreted by the CMake interpreter, specifically by ConverterTarget, flags and defines which are specific for individual files are accumulated for the entire target https://github.com/mesonbuild/meson/blob/1840bb02ba741fb62a8d613a71431a8d7fa86a00/mesonbuild/cmake/interpreter.py#L283

Example

I've tried to build vvdec project as a subproject, but the compilation failed due to mismatch in the flags and defines.

This project uses specific defines for different groups of files in one target: https://github.com/fraunhoferhhi/vvdec/blob/v3.0.0/source/Lib/vvdec/CMakeLists.txt#L93

  set_property( SOURCE ${X86_SSE41_SRC_FILES} APPEND PROPERTY COMPILE_DEFINITIONS USE_SSE41 )
...
  set_property( SOURCE ${X86_AVX2_SRC_FILES}  APPEND PROPERTY COMPILE_DEFINITIONS USE_AVX2 )

In the build.ninja generated by cmake it is respected:

build source/Lib/vvdec/CMakeFiles/vvdec_x86_simd.dir/__/CommonLib/x86/sse41/Quant_sse41.cpp.o: CXX_COMPILER__vvdec_x86_simd_unscanned_RelWithDebInfo /home/molejnik/Workspace/OCP-5938/flu-plugins/subprojects/vvcdec_fraunhofer/source/Lib/CommonLib/x86/sse41/Quant_sse41.cpp || cmake_object_order_depends_target_vvdec_x86_simd
  DEFINES = -DTARGET_SIMD_X86 -DVVDEC_SOURCE -DUSE_SSE41
  DEP_FILE = source/Lib/vvdec/CMakeFiles/vvdec_x86_simd.dir/__/CommonLib/x86/sse41/Quant_sse41.cpp.o.d
  FLAGS = -O2 -g -DNDEBUG -std=gnu++14 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -msse4.1 -Wall -Wno-unused-function -Wno-sign-compare -fdiagnostics-show-option -Wno-ignored-attributes -Werror -msse4.1
 ...
build source/Lib/vvdec/CMakeFiles/vvdec_x86_simd.dir/__/CommonLib/x86/avx2/Quant_avx2.cpp.o: CXX_COMPILER__vvdec_x86_simd_unscanned_RelWithDebInfo /home/molejnik/Workspace/OCP-5938/flu-plugins/subprojects/vvcdec_fraunhofer/source/Lib/CommonLib/x86/avx2/Quant_avx2.cpp || cmake_object_order_depends_target_vvdec_x86_simd
  DEFINES = -DTARGET_SIMD_X86 -DVVDEC_SOURCE -DUSE_AVX2
  DEP_FILE = source/Lib/vvdec/CMakeFiles/vvdec_x86_simd.dir/__/CommonLib/x86/avx2/Quant_avx2.cpp.o.d
  FLAGS = -O2 -g -DNDEBUG -std=gnu++14 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -msse4.1 -Wall -Wno-unused-function -Wno-sign-compare -fdiagnostics-show-option -Wno-ignored-attributes -Werror -mavx2

however, after parsing and preparing the AST file, flags and defines for each group are accumulated into cpp_args for the entire target:

vvdec_x86_simd_src = files(
  'source/Lib/CommonLib/x86/sse41/AdaptiveLoopFilter_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/Buffer_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/InterPred_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/InterpolationFilter_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/IntraPred_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/LoopFilter_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/Picture_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/Quant_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/RdCost_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/SampleAdaptiveOffset_sse41.cpp',
  'source/Lib/CommonLib/x86/sse41/Trafo_sse41.cpp',
  'source/Lib/FilmGrain/FilmGrainImpl_sse41.cpp',
  'source/Lib/CommonLib/x86/avx2/AdaptiveLoopFilter_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/Buffer_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/InterPred_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/InterpolationFilter_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/IntraPred_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/LoopFilter_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/Picture_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/Quant_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/RdCost_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/SampleAdaptiveOffset_avx2.cpp',
  'source/Lib/CommonLib/x86/avx2/Trafo_avx2.cpp',
  'source/Lib/FilmGrain/FilmGrainImpl_avx2.cpp'
)
vvdec_x86_simd = static_library(
  'vvdec_x86_simd',
  vvdec_x86_simd_src,
  build_by_default : false,
  link_args : [],
  link_with : [],
  include_directories : vvdec_x86_simd_inc,
  install : false,
  override_options : ['cpp_std=gnu++14'],
  objects : [],
  cpp_args : [
    '-O2',
    '-g',
    '-DNDEBUG',
    '-fvisibility=hidden',
    '-fvisibility-inlines-hidden',
    '-msse4.1',
    '-Wno-unused-function',
    '-Wno-sign-compare',
    '-fdiagnostics-show-option',
    '-Wno-ignored-attributes',
    '-msse4.1',
    '-DTARGET_SIMD_X86',
    '-DUSE_SSE41',
    '-DVVDEC_SOURCE',
    '-mavx2',
    '-DUSE_AVX2'
  ],
  pic : true
)

This results in compilation/linking errors.

dcbaker commented 3 weeks ago

This is somewhat difficult to fix ATM, because we don't have an equivalent of setting arguments on a single source, unless that source is compiled as an independent static_library, and then linked in. I have some thoughts on this, but I haven't gotten around to it yet, and the CMake portion will likely not work until we have that.