diff --git a/pkgs/c/compat.catch2.lua b/pkgs/c/compat.catch2.lua index d17ff653..7fe7d09d 100644 --- a/pkgs/c/compat.catch2.lua +++ b/pkgs/c/compat.catch2.lua @@ -118,10 +118,46 @@ package = { -- Union of both layouts. v2 resolves */single_include, v3 resolves -- */src; the other one matches nothing and is skipped. mcpp_generated - -- carries catch2/catch_user_config.hpp for v3. - include_dirs = { "*/single_include", "*/src", "mcpp_generated" }, + -- carries catch2/catch_user_config.hpp for v3 and the v2 shim. + -- + -- ORDER MATTERS: mcpp_generated goes FIRST so the shim below is found + -- before upstream's own catch2/catch.hpp, which it then reaches with + -- #include_next. This is the only lever available — a descriptor's + -- cflags do not reach CONSUMER translation units (verified: a consumer + -- TU gets the include_dirs and -std, nothing else), and the consumer is + -- exactly who includes catch.hpp. + include_dirs = { "mcpp_generated", "*/single_include", "*/src" }, generated_files = { + -- v2 only, and only because upstream 2.13.10 is wrong: its + -- single header calls `new(std::nothrow)` twice (catch.hpp:977 + -- and :14594) and never includes . libstdc++ happens to + -- drag in through another header, so gcc has always been + -- green; libc++ does not, so every clang consumer fails with + -- "no member named 'nothrow' in namespace 'std'". Catch2 v2 is + -- EOL upstream, so this is not getting fixed there. + -- + -- A shim rather than a patched copy of the 17k-line header: it + -- keeps the sha256-pinned tarball as the only source of truth. + -- #include_next resumes the search AFTER this file's directory, + -- which is why mcpp_generated must sort first in include_dirs. + -- + -- CAVEAT for whoever touches the v2/v3 discriminator: this file + -- is on the include path for BOTH majors, so + -- `__has_include()` is now unconditionally true + -- and can never be used to detect v2. (On v3 it would be found + -- and then fail in #include_next, since there is no upstream + -- catch.hpp behind it — but __has_include never gets that far.) + -- The existing discriminator probes catch_all.hpp instead, which + -- is unaffected. See the header comment for why per-version + -- blocks (mcpp#290) are the real answer here. + ["mcpp_generated/catch2/catch.hpp"] = [==[ +#ifndef MCPP_COMPAT_CATCH2_NOTHROW_SHIM +#define MCPP_COMPAT_CATCH2_NOTHROW_SHIM +#include +#include_next +#endif +]==], -- v3 only. Upstream ships catch_user_config.hpp.in and lets CMake -- materialise it. Only the two VALUE defines are mandatory — -- everything else in the .in is a #cmakedefine, i.e. absent means diff --git a/pkgs/c/compat.ffmpeg.lua b/pkgs/c/compat.ffmpeg.lua index df08cce9..4796007c 100644 --- a/pkgs/c/compat.ffmpeg.lua +++ b/pkgs/c/compat.ffmpeg.lua @@ -4,8 +4,13 @@ -- Data/logic separation (mcpp 0.0.100 design): sources glob-compressed, list -- files shared when identical, config.{h,asm}/config_components.{h,asm} split -- into a neutral .base + tiny per-OS deltas. ffmpeg source root sits on --- include_dirs_after (-idirafter, mcpp#249) so libc++ is not shadowed --- by ffmpeg's VERSION file on case-insensitive macOS. +-- include_dirs_after (-idirafter, mcpp#249) on macOS/windows so libc++ +-- is not shadowed by ffmpeg's VERSION file on their case-insensitive +-- filesystems. On linux it is on plain include_dirs INSTEAD: -idirafter ranks +-- below the system dirs, so a host-installed ffmpeg (/usr/include/x86_64-linux- +-- gnu on Debian/Ubuntu) would otherwise outrank the vendored 8.1.2 tree. Never +-- both -- a dir named on -I and -idirafter dedupes to the last one, cancelling +-- the -I. package = { spec = "1", namespace = "compat", name = "ffmpeg", description = "FFmpeg 8.1.2 multimedia libraries, full source build (LGPL profile, multi-platform)", @@ -35,9 +40,6 @@ package = { "mcpp_generated/libavdevice", "*/libavcodec", }, - include_dirs_after = { - "*", - }, cflags = { "-DHAVE_AV_CONFIG_H", "-D_ISOC11_SOURCE", @@ -7791,6 +7793,7 @@ static const FFOutputFormat * const muxer_list[] = { "*/libavfilter/x86", "*/libswscale/x86", "*/libswresample/x86", + "*", }, flags = { { glob = "**/*.asm", asmflags = { "-Pconfig.asm" } }, @@ -8254,6 +8257,9 @@ static const URLProtocol * const url_protocols[] = { ldflags = { "-lm", }, + include_dirs_after = { + "*", + }, sources = { "*/libavcodec/{012v,4xm,8bps,8svx,a64multienc,aac_ac3_parser,aac_parser,aaccoder,aacenc,aacenc_is,aacenc_tns,aacenctab,aacps_common,aacps_fixed,aacps_float,aacpsdsp_fixed,aacpsdsp_float,aacpsy,aacsbr,aacsbr_fixed,aactab,aandcttab,aasc,ac3,ac3_channel_layout_tab,ac3_parser,ac3dec_data,ac3dec_fixed,ac3dec_float,ac3dsp,ac3enc,ac3enc_fixed,ac3enc_float,ac3tab,acelp_filters,acelp_pitch_delay,acelp_vectors,adpcm,adpcm_data,adpcmenc,adts_header,adts_parser,adx,adx_parser,adxdec,adxenc,agm,aic,alac,alac_data,alacdsp,alacenc,aliaspixdec,aliaspixenc,allcodecs,alsdec,amr_parser,amrnbdec,amrwbdec,anm,ansi,aom_film_grain,apac,apedec,aptx,aptxdec,aptxenc,apv_decode,apv_dsp,apv_entropy,apv_parser,arbc,argo,ass,ass_split,assdec,assenc,asv,asvdec,asvenc,atrac,atrac1,atrac3,atrac3plus,atrac3plusdec,atrac3plusdsp,atrac9dec,atsc_a53,audio_frame_queue,audiodsp,aura,av1_parse,av1_parser,av1dec,avcodec,avdct,avrndec,avs,avs2,avs2_parser,avs3_parser,avuidec,avuienc,bethsoftvideo,bfi,bgmc,bink,binkaudio,binkdsp,bintext,bitpacked_dec,bitpacked_enc,bitstream,bitstream_filters,blockdsp,bmp,bmp_parser,bmpenc,bmvaudio,bmvvideo,bonk,brenderpix,bsf,bswapdsp,c93,cabac,canopus,cavs,cavs_parser,cavsdata,cavsdec,cavsdsp,cbrt_data,cbrt_data_fixed,cbrt_tablegen_common,cbs,cbs_apv,cbs_av1,cbs_bsf,cbs_h264,cbs_h2645,cbs_h265,cbs_h266,cbs_lcevc,cbs_mpeg2,cbs_sei,cbs_vp8,cbs_vp9,ccaption_dec,cdgraphics,cdtoons,cdxl,celp_filters,celp_math,cfhd,cfhddata,cfhddsp,cfhdenc,cfhdencdsp,cga_data,cinepak,cinepakenc,clearvideo,cljrdec,cljrenc,cllc,cngdec,cngenc,codec_desc,codec_par,cook,cook_parser,cpia,cri,cri_parser,cscd,cyuv,d3d11va,dca,dca_core,dca_exss,dca_lbr,dca_parser,dca_sample_rate_tab,dca_xll,dcaadpcm,dcadata,dcadct,dcadec,dcadsp,dcaenc,dcahuff,dct32_fixed,dct32_float,dds,decode,dfa,dfpwmdec,dfpwmenc,dirac,dirac_arith,dirac_dwt,dirac_parser,dirac_vlc,diracdec,diracdsp,diractab,dnxhd_parser,dnxhddata,dnxhddec,dnxhdenc,dnxuc_parser,dolby_e,dolby_e_parse,dolby_e_parser,dovi_rpu,dovi_rpudec,dovi_rpuenc,dpcm,dpx,dpx_parser,dpxenc,dsd,dsddec,dsicinaudio,dsicinvideo,dss_sp,dstdec,dv,dv_profile,dvaudio_parser,dvaudiodec,dvbsub_parser,dvbsubdec,dvbsubenc,dvd_nav_parser,dvdata,dvdec,dvdsub,dvdsub_parser,dvdsubdec,dvdsubenc,dvenc,dxtory,dxv,dxvenc,dynamic_hdr_vivid,eac3_data,eac3enc,eacmv,eaidct,eamad,eatgq,eatgv,eatqi,elbg,encode,error_resilience,escape124,escape130,evc_parse,evc_parser,evc_ps,evrcdec,executor,exif,faandct,faanidct,fastaudio,faxcompr,fdctdsp,ffv1,ffv1_parse,ffv1_parser,ffv1dec,ffv1enc,ffwavesynth,fic,fits,fitsdec,fitsenc,flac,flac_parser,flacdata,flacdec,flacdsp,flacenc,flacencdsp,flicvideo,flvdec,flvenc,fmtconvert,fmvc,frame_thread_encoder,fraps,frwu,ftr,ftr_parser,g722,g722dec,g722dsp,g722enc,g723_1,g723_1_parser,g723_1dec,g723_1enc,g726,g728dec,g729_parser,g729dec,g729postfilter,gdv,gemdec,get_buffer,gif,gif_parser,gifdec,golomb,gsm_parser,gsmdec,gsmdec_data,h261,h261_parser,h261data,h261dec,h261enc,h263,h263_parser,h263data,h263dec,h263dsp,h2645_parse,h2645_sei,h2645_vui,h2645data,h264_cabac,h264_cavlc,h264_direct,h264_levels,h264_loopfilter,h264_mb,h264_parse,h264_parser,h264_picture,h264_ps,h264_refs,h264_sei,h264_slice,h264chroma,h264data,h264dec,h264dsp,h264idct,h264pred,h264qpel,h265_profile_level,h274,hap,hapdec,hashtable,hcadec,hcom,hdr_parser,hdrdec,hdrenc,hnm4video,hpeldsp,hq_common,hq_hqa,hq_hqadsp,hqx,hqxdsp,htmlsubtitles,huffman,huffyuv,huffyuvdec,huffyuvdsp,huffyuvenc,huffyuvencdsp,idcinvideo,idctdsp,iff,ilbcdec,imc,imgconvert,imm4,imm5,imx,indeo2,indeo3,indeo4,indeo5,intelh263dec,interplayacm,interplayvideo,intrax8,intrax8dsp,ipu_parser,ituh263dec,ituh263enc,ivi,ivi_dsp,j2kenc,jacosubdec,jfdctfst,jfdctint,jni,jpeg2000,jpeg2000_parser,jpeg2000dec,jpeg2000dsp,jpeg2000dwt,jpeg2000htdec,jpegls,jpeglsdec,jpeglsenc,jpegquanttables,jpegtables,jpegxl_parse,jpegxl_parser,jpegxs_parser,jrevdct,jvdec,kbdwin,kgv1dec,kmvc,lagarith,lagarithrac,latm_parser,lcevc_parser,lcevctab,lcldec,leaddec,ljpegenc,loco,lossless_audiodsp,lossless_videodsp,lossless_videoencdsp,lpc,lsp,lzf,lzw,lzwenc,m101,mace,magicyuv,magicyuvenc,mathtables,mdec,me_cmp,mediacodec,metasound,microdvddec,midivid,mimic,misc4,misc4_parser,mjpeg_parser,mjpegbdec,mjpegdec,mjpegdec_common,mjpegenc,mjpegenc_common,mjpegenc_huffman,mlp,mlp_parse,mlp_parser,mlpdec,mlpdsp,mlpenc,mlz,mmvideo,mobiclip,motion_est,motionpixels,movtextdec,movtextenc,mpc,mpc7,mpc8,mpeg12,mpeg12data,mpeg12dec,mpeg12enc,mpeg12framerate,mpeg4audio,mpeg4audio_sample_rates,mpeg4video,mpeg4video_parser,mpeg4videodec,mpeg4videodsp,mpeg4videoenc,mpeg_er,mpegaudio,mpegaudio_parser,mpegaudiodata,mpegaudiodec_common,mpegaudiodec_fixed,mpegaudiodec_float,mpegaudiodecheader,mpegaudiodsp,mpegaudiodsp_data,mpegaudiodsp_fixed,mpegaudiodsp_float,mpegaudioenc,mpegaudiotabs,mpegpicture,mpegutils,mpegvideo,mpegvideo_dec,mpegvideo_enc,mpegvideo_motion,mpegvideo_parser,mpegvideo_unquantize,mpegvideodata,mpegvideoencdsp,mpl2dec,mqc,mqcdec,mqcenc,msgsmdec,msmpeg4,msmpeg4_vc1_data,msmpeg4data,msmpeg4dec,msmpeg4enc,msp2dec,msrle,msrledec,msrleenc,mss1,mss12,mss2,mss2dsp,mss3,mss34dsp,mss4,msvideo1,msvideo1enc,mv30,mvcdec,mxpegdec,nellymoser,nellymoserdec,nellymoserenc,notchlc,null,nuv,on2avc,on2avcdata,options,osq,packet,pafaudio,pafvideo,pamenc,parser,parsers,pcm,pcm-bluray,pcm-blurayenc,pcm-dvd,pcm-dvdenc,pcx,pcxenc,pgssubdec,pgxdec,photocd,pictordec,pixblockdsp,pixlet,png_parser,pnm,pnm_parser,pnmdec,pnmenc,profiles,prores_parser,prores_raw,prores_raw_parser,proresdata,proresdec,proresdsp,proresenc_anatoliy,proresenc_kostya,proresenc_kostya_common,prosumer,psd,psymodel,pthread,pthread_frame,pthread_slice,ptx,qcelpdec,qdm2,qdmc,qdrw,qoadec,qoi_parser,qoidec,qoienc,qpeg,qpeldsp,qsv_api,qtrle,qtrleenc,r210dec,r210enc,ra144,ra144dec,ra144enc,ra288,ralf,rangecoder,ratecontrol,raw,rawdec,rawenc,realtextdec,rka,rl,rl2,rle,roqaudioenc,roqvideo,roqvideodec,roqvideoenc,rpza,rpzaenc,rtjpeg,rtv1,rv10,rv10enc,rv20enc,rv30,rv30dsp,rv34,rv34_parser,rv34dsp,rv40,rv40dsp,rv60dec,rv60dsp,s302m,s302menc,samidec,sanm,sbc,sbc_parser,sbcdec,sbcdsp,sbcenc,sbrdsp,sbrdsp_fixed,scpr,sga,sgidec,sgienc,sgirledec,sheervideo,shorten,simple_idct,sinewin,sipr,sipr16k,sipr_parser,siren,smacker,smc,smcenc,smpte_436m,snappy,snow,snow_dwt,snowdec,snowenc,sonic,sp5xdec,speedhq,speedhqdec,speedhqenc,speexdec,srtdec,srtenc,startcode,subviewerdec,sunrast,sunrastenc,svq1,svq1dec,svq1enc,svq3,synth_filter,tak,tak_parser,takdec,takdsp,targa,targa_y216dec,targaenc,textdec,texturedsp,texturedspenc,threadprogress,tiertexseqv,tiff,tiff_common,tiffenc,tmv,to_upper4,tpeldsp,truemotion1,truemotion2,truemotion2rt,truespeech,tscc2,tta,ttadata,ttadsp,ttaenc,ttaencdsp,ttmlenc,twinvq,twinvqdec,txd,ulti,utils,utvideodec,utvideodsp,utvideoenc,v210dec,v210enc,v210x,v308dec,v308enc,v408dec,v408enc,v410dec,v410enc,vb,vble,vbndec,vbnenc,vc1,vc1_block,vc1_loopfilter,vc1_mc,vc1_parser,vc1_pred,vc1data,vc1dec,vc1dsp,vc2enc,vc2enc_dwt,vcr1,version,videodsp,vima,vlc,vmdaudio,vmdvideo,vmixdec,vmnc,vorbis,vorbis_data,vorbis_parser,vorbisdec,vorbisdsp,vorbisenc,vp3,vp3_parser,vp3dsp,vp5,vp56,vp56data,vp5dsp,vp6,vp6dsp,vp8,vp8_parser,vp8data,vp8dsp,vp9,vp9_parser,vp9block,vp9data,vp9dsp,vp9dsp_10bpp,vp9dsp_12bpp,vp9dsp_8bpp,vp9lpf,vp9mvs,vp9prob,vp9recon,vpx_rac,vqavideo,vqcdec,vvc_parser,wavarc,wavpack,wavpackdata,wavpackenc,wbmpdec,wbmpenc,webp,webp_parser,webvttdec,webvttenc,wma,wma_common,wma_freqs,wmadec,wmaenc,wmalosslessdec,wmaprodec,wmavoice,wmv2data,wmv2dec,wmv2dsp,wmv2enc,wnv1,wrapped_avframe,ws-snd1,xan,xbm_parser,xbmdec,xbmenc,xface,xfacedec,xfaceenc,xiph,xl,xma_parser,xpmdec,xsubdec,xsubenc,xvididct,xwd_parser,xwddec,xwdenc,xxan,y41pdec,y41penc,ylc,yop,yuv4dec,yuv4enc}.c", "*/libavcodec/aac/{aacdec,aacdec_ac,aacdec_fixed,aacdec_float,aacdec_lpd,aacdec_tab,aacdec_usac,aacdec_usac_mps212}.c", @@ -8578,6 +8584,9 @@ static const URLProtocol * const url_protocols[] = { "-luuid", "-lshlwapi", }, + include_dirs_after = { + "*", + }, include_dirs = { "*/libavutil/x86", "*/libavcodec/x86", diff --git a/pkgs/o/opencv.lua b/pkgs/o/opencv.lua deleted file mode 100644 index 8bc7b1dc..00000000 --- a/pkgs/o/opencv.lua +++ /dev/null @@ -1,112 +0,0 @@ --- ⚠️ 已冻结 —— 本条目不再接收新版本。 --- --- 本包已迁往 `opencv:opencv@5.0.0`(见 pkgs/o/opencv.opencv.lua),理由是命名空间说的是这个库是谁的、 --- 版本说的是你拿到的是哪一版上游;`mcpplibs` 是 mcpp 的默认命名空间,两者都不是它 --- 该表达的东西。规则与全生态迁移表:mcpp-index#163。 --- --- 这里保留而不删除:已经在用 `mcpplibs:opencv` 的消费者继续解析得到它。新版本只在新条目下 --- 发布。迁移方式是把依赖写成限定形式 —— --- --- [dependencies.opencv] --- opencv = "5.0.0" --- --- Form A descriptor: the public opencv module package ships its own --- mcpp.toml. mcpp's default lookup finds /*/mcpp.toml inside --- the GitHub source tarball wrap. --- --- Since 0.0.7 the package is SINGLE-REPO: opencv-m carries both the C++23 --- module layer (import opencv.cv; and the per-module interfaces) and the --- full OpenCV 5.0.0 source build. The upstream sources are vendored in the --- release tarball (third_party/opencv-5.0.0/ — pruned import of the official --- tag, sha256-pinned, patch-free) together with the frozen per-OS configure --- snapshots (gen/), so no CMake runs on the consumer side and this index no --- longer carries a compat.opencv descriptor: it was retired in the same --- change, along with compat.opencv-unifont and tools/compat-opencv/. --- --- The only remaining external dependency is compat.ffmpeg, declared by the --- package's own mcpp.toml for the videoio FFmpeg backend. --- --- Three platforms, one OS-neutral tarball: the per-OS differences live in the --- package's gen/ snapshots and mcpp.toml, and all three are verified by the --- package's own CI (linux gcc/llvm/musl-static, macOS llvm, windows llvm). --- Optional features: `dnn` adds the import opencv.dnn; interface plus the --- underlying dnn sources (mlas on linux/macOS; the built-in fast_gemm backend --- on windows, where upstream mlas x86 assembly is GAS/ELF and clang-cl cannot --- emit COFF from it); `unifont` embeds the CJK font behind FontFace("uni") — --- `opencv = { features = ["dnn"] }`. --- --- Requires mcpp >= 0.0.102: per-OS feature semantics (mcpp#253, 0.0.101) plus --- the windows scan-deps command-line fix (mcpp#261, 0.0.102). As a consumed --- dependency the package's own TUs compile from under the ~124-char registry --- xpkgs path rather than a short checkout, which pushed the clang scan-deps --- command past cmd.exe's 8191-char ceiling under 0.0.101; 0.0.102 drops the --- `cmd /c` redirect wrapper (clang-scan-deps -o) and restores the 32767 limit. --- --- 0.0.10: the per-glob flag tables moved into OS-conditional --- [target.'cfg(...)'.build.flags] sections (mcpp#258, same 0.0.102 floor) — --- entries whose predicate does not match the resolved target never enter the --- glob table, so consumer builds no longer emit the ~26 structural dead-glob --- warnings (windows stub globs + neon TUs on linux, symmetric elsewhere). --- -package = { - spec = "1", - name = "opencv", - namespace = "mcpplibs", - description = "C++23 module package for OpenCV 5 (import opencv.cv) — vendored full source build, C++ API unchanged", - licenses = {"MIT"}, -- module layer; the vendored OpenCV itself is Apache-2.0 - repo = "https://github.com/Sunrisepeak/opencv-m", - type = "package", - - xpm = { - linux = { - ["0.0.10"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.10.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.10/opencv-m-0.0.10.tar.gz", - }, - sha256 = "4a8cb551e6a9a1f39c2a70fc1fdd2719200a94fbb5b8d50f7e99e3e88c9ab801", - }, - ["0.0.9"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.9.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.9/opencv-m-0.0.9.tar.gz", - }, - sha256 = "888c45ad6b558d4172ac570ff97f3c931c8a3a229e294574da788221938d768a", - }, - }, - macosx = { - ["0.0.10"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.10.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.10/opencv-m-0.0.10.tar.gz", - }, - sha256 = "4a8cb551e6a9a1f39c2a70fc1fdd2719200a94fbb5b8d50f7e99e3e88c9ab801", - }, - ["0.0.9"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.9.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.9/opencv-m-0.0.9.tar.gz", - }, - sha256 = "888c45ad6b558d4172ac570ff97f3c931c8a3a229e294574da788221938d768a", - }, - }, - windows = { - ["0.0.10"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.10.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.10/opencv-m-0.0.10.tar.gz", - }, - sha256 = "4a8cb551e6a9a1f39c2a70fc1fdd2719200a94fbb5b8d50f7e99e3e88c9ab801", - }, - ["0.0.9"] = { - url = { - GLOBAL = "https://github.com/Sunrisepeak/opencv-m/archive/refs/tags/v0.0.9.tar.gz", - CN = "https://gitcode.com/mcpp-res/opencv/releases/download/v0.0.9/opencv-m-0.0.9.tar.gz", - }, - sha256 = "888c45ad6b558d4172ac570ff97f3c931c8a3a229e294574da788221938d768a", - }, - }, - }, - - -- (no `mcpp` field -- default lookup will find /*/mcpp.toml) -} diff --git a/tests/examples/opencv-module-dnn/mcpp.toml b/tests/examples/opencv-module-dnn/mcpp.toml index a83cdcb1..15539c78 100644 --- a/tests/examples/opencv-module-dnn/mcpp.toml +++ b/tests/examples/opencv-module-dnn/mcpp.toml @@ -3,7 +3,7 @@ # opencv.dnn interface, so `import opencv.dnn;` is available. All three # platforms (mlas on linux/macOS, built-in fast_gemm on windows). # Overrides the workspace-root redirect: root declares `compat`, this member -# needs `default`. A member-level [indices] REPLACES the inherited table rather +# needs `opencv`. A member-level [indices] REPLACES the inherited table rather # than merging with it, which is what keeps this to ONE project index repo — # two repos pointing at the same tree make every lookup ambiguous. [indices] diff --git a/tests/examples/opencv-module-unifont/mcpp.toml b/tests/examples/opencv-module-unifont/mcpp.toml index 82e25df5..f07da8b2 100644 --- a/tests/examples/opencv-module-unifont/mcpp.toml +++ b/tests/examples/opencv-module-unifont/mcpp.toml @@ -2,7 +2,7 @@ # ["unifont"] }` embeds the CJK font (no new module surface), so FontFace("uni") # renders CJK through `import opencv.cv;`. Exercised on linux and macOS. # Overrides the workspace-root redirect: root declares `compat`, this member -# needs `default`. A member-level [indices] REPLACES the inherited table rather +# needs `opencv`. A member-level [indices] REPLACES the inherited table rather # than merging with it, which is what keeps this to ONE project index repo — # two repos pointing at the same tree make every lookup ambiguous. [indices] diff --git a/tests/examples/opencv-module/mcpp.toml b/tests/examples/opencv-module/mcpp.toml index 1a2b464b..fb923245 100644 --- a/tests/examples/opencv-module/mcpp.toml +++ b/tests/examples/opencv-module/mcpp.toml @@ -1,11 +1,11 @@ -# Public `opencv` C++23-module package test (bare-name consumption from the -# builtin default namespace — resolved against THIS checkout via the -# workspace-root `[indices]` redirect, which every member inherits). +# Public `opencv` C++23-module package test (QUALIFIED consumption from the +# `opencv` namespace — `mcpplibs:opencv` was frozen by #165 and deleted once +# every consumer had moved, so the bare name resolves to nothing at all now). # Since opencv 0.0.7 the package is single-repo: the OpenCV sources are # vendored in its own release tarball, so this member exercises the whole # source build on all three platforms. # Overrides the workspace-root redirect: root declares `compat`, this member -# needs `default`. A member-level [indices] REPLACES the inherited table rather +# needs `opencv`. A member-level [indices] REPLACES the inherited table rather # than merging with it, which is what keeps this to ONE project index repo — # two repos pointing at the same tree make every lookup ambiguous. [indices] diff --git a/tools/compat-ffmpeg/gen_multiplatform.py b/tools/compat-ffmpeg/gen_multiplatform.py index 6c3646ec..6eda5ae2 100644 --- a/tools/compat-ffmpeg/gen_multiplatform.py +++ b/tools/compat-ffmpeg/gen_multiplatform.py @@ -11,8 +11,12 @@ that #includes the base and adds only its deltas (every CONFIG_/HAVE_ macro is an independent define, so a macro is in the base XOR exactly one delta — no redef) - * ffmpeg source root ("*", "*/libavcodec") → include_dirs_after (mcpp#249 - -idirafter, so libc++ wins over ffmpeg VERSION) + * ffmpeg source root → per-OS: include_dirs_after on macosx/windows (mcpp#249 + -idirafter, so libc++ wins over ffmpeg VERSION), + plain include_dirs on linux, so a host-installed ffmpeg in + /usr/include cannot outrank the vendored tree. Never both + at once — the compiler dedupes to the last position and + the -I would be cancelled (see ROOT_ON_PLAIN_I) Self-checks: per OS, base∪delta reconstructs the original #define set exactly. """ import sys, re @@ -43,6 +47,33 @@ # style includes need it there (on -idirafter, windows clang-MSVC fails to find # them, e.g. opus/parser.c → ParseContext undefined). ROOT_INCLUDE_AFTER = ["*"] +# ...but -idirafter ranks BELOW the system include dirs, and that is a hole on +# any host that has ffmpeg dev headers installed. Debian/Ubuntu put them in +# /usr/include/x86_64-linux-gnu (multiarch, a DEFAULT search dir), so with only +# -idirafter the vendored 8.1.2 tree loses every `#include "libavutil/..."` to +# the host's ffmpeg. That is not a graceful downgrade: the global +# -DHAVE_AV_CONFIG_H below makes the host's PUBLIC headers pull private ones +# the dev package does not ship ('x86/bswap.h', libavutil/internal.h), and the +# 6.x/8.x type skew hits too (incomplete `enum AVAlphaMode`, SwsContext missing +# its typedef). It stayed invisible because the toolchain that built this in CI +# and locally was gcc with --sysroot into a clean xlings subos, where no libav* +# exists; switching to llvm (no sysroot) exposes the host tree. +# +# So the root is placed PER OS — and it has to be one or the other, never both: +# a directory named on -I *and* -idirafter is deduplicated by the compiler down +# to its LAST occurrence, so keeping a redundant -idirafter copy silently +# cancels the -I and the system headers win anyway. Verified on clang 22.1.8: +# identical command line, dropping only the duplicate -idirafter, compiles. +# +# linux → plain -I. Case-sensitive filesystem, so ffmpeg's VERSION file can +# never shadow libc++ ; and it is the one platform with a +# system ffmpeg to lose to. +# macosx → -idirafter. Case-insensitive APFS/HFS+ — plain -I is exactly what +# #249 fixed. Homebrew ffmpeg lives outside the default search path, +# so there is nothing to outrank anyway. +# windows → -idirafter. NTFS is case-insensitive too, so -I would bring #249 +# straight back, and MSVC/clang-cl system dirs carry no libav*. +ROOT_ON_PLAIN_I = {"linux"} X86_INCLUDE = ["*/libavutil/x86", "*/libavcodec/x86", "*/libavfilter/x86", "*/libswscale/x86", "*/libswresample/x86"] NEUTRAL_CFLAGS = ["-DHAVE_AV_CONFIG_H", "-D_ISOC11_SOURCE", "-D_FILE_OFFSET_BITS=64", @@ -207,8 +238,16 @@ def per_os_block(o): srcs = compress_sources(raw) parts = [f' cflags = {L(PER_OS_CFLAGS[o], 12)},', f' ldflags = {L(PER_OS_LDFLAGS[o], 12)},'] + # Root last: it must keep ranking below '*/libavcodec' (neutral) and the + # x86 dirs, which is the order the -idirafter form already had. Only its + # position relative to the SYSTEM dirs changes. + per_os_inc = (X86_INCLUDE if o in X86 else []) + ( + ROOT_INCLUDE_AFTER if o in ROOT_ON_PLAIN_I else []) + if o not in ROOT_ON_PLAIN_I: + parts.append(f' include_dirs_after = {L(ROOT_INCLUDE_AFTER, 12)},') + if per_os_inc: + parts.append(f' include_dirs = {L(per_os_inc, 12)},') if o in X86: - parts.append(f' include_dirs = {L(X86_INCLUDE, 12)},') parts.append(' flags = {\n { glob = "**/*.asm", asmflags = { "-Pconfig.asm" } },\n },') parts.append(f' sources = {L(srcs, 12)},') parts.append(' generated_files = ' + gen_block(per_os_gen[o], 12)) @@ -231,8 +270,13 @@ def per_os_block(o): -- Data/logic separation (mcpp 0.0.100 design): sources glob-compressed, list -- files shared when identical, config.{{h,asm}}/config_components.{{h,asm}} split -- into a neutral .base + tiny per-OS deltas. ffmpeg source root sits on --- include_dirs_after (-idirafter, mcpp#249) so libc++ is not shadowed --- by ffmpeg's VERSION file on case-insensitive macOS. +-- include_dirs_after (-idirafter, mcpp#249) on macOS/windows so libc++ +-- is not shadowed by ffmpeg's VERSION file on their case-insensitive +-- filesystems. On linux it is on plain include_dirs INSTEAD: -idirafter ranks +-- below the system dirs, so a host-installed ffmpeg (/usr/include/x86_64-linux- +-- gnu on Debian/Ubuntu) would otherwise outrank the vendored 8.1.2 tree. Never +-- both -- a dir named on -I and -idirafter dedupes to the last one, cancelling +-- the -I. package = {{ spec = "1", namespace = "compat", name = "{NAME}", description = "FFmpeg {VER} multimedia libraries, full source build (LGPL profile, multi-platform)", @@ -244,7 +288,6 @@ def per_os_block(o): c_standard = "c17", targets = {{ ffmpeg = {{ kind = "lib" }} }}, include_dirs = {L(NEUTRAL_INCLUDE, 8)}, - include_dirs_after = {L(ROOT_INCLUDE_AFTER, 8)}, cflags = {L(NEUTRAL_CFLAGS, 8)}, flags = {{ {chr(10).join(bflags)}