scapix-com / scapix

Scapix Language Bridge

Home Page:https://www.scapix.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Weird source files in multilevel CMake build

TimPushkin opened this issue · comments

I have a CMake project with layout like this:

project_root/
    examples/
        CMakeLists.txt
        <some executable examples>
    external/
        CMakeLists.txt
        scapix/
                CMakeLists.txt  <-- Scapix is loaded here
    include/
        <headers to parse are here>
    src/
        CMakeLists.txt  <-- The main library target is created here
        <sources are here>
    CMakeLists.txt

The top-level CMake file includes other files via add_subdirectory: firstly the main target is created in src subfolder via add_library, then Scapix and other libraries are configured, then examples subfolder is added the same way, containing some executable targets created via add_executable (the library is linked to them). The project builds and works fine without Scapix.

The problem is that when I add Scapix to the project with

scapix_bridge_headers(<main library target> com.example.something <path to SomeClass.h>)

and run CMake with -DSCAPIX_BRIDGE=java I get the following errors at configure time:

CMake Error at src/CMakeLists.txt:3 (add_library):
  Cannot find source file:

    <my project path>/generated/bridge/java/SomeClass.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc


CMake Error at examples/CMakeLists.txt:2 (add_executable):
  Cannot find source file:

    <my project path>/generated/bridge/java/com/example/something/SomeClass.java

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc

I do not specify the missing files by myself, it seems like Scapix adds them to the targets somehow.

I can get rid of the first one if I place the content of the CMake file that loads Scapix into the CMake file that creates the library target (src/CMakeLists.txt), but then the second one remains, and I can get rid of the second one if I place it into the CMake file that creates the example target (examples/CMakeLists.txt), but then the first one remains.

Is it possible to fix these errors without throwing all CMake code into a single CMake file?

Thank you for reporting this.

Is your project available on github?

If not, can you please post skeleton CMake files, so I can setup the test project?

I tried to recreate your setup, here:

https://github.com/scapix-com/bug_multilevel

However, I do not get the error, everything works fine.

I gave you write access to this repository, can you please add necessary modifications to get the error?

Thanks.

I managed to recreate the error and commited it to the repository. It represents the current state of my project: if I use CMake 3.18 then the errors described above appear, if I use CMake 3.20 or higher then the configuration completes without errors, but build fails because the bridge file for SomeClass.cpp doesn't get generated and thus cannot be found.

Thanks, I found that simply setting cmake_minimum_required(VERSION 3.18) in my original test leads to error.

Starting from CMake 3.20 the error disappears because of this change in CMake 3.20:
https://cmake.org/cmake/help/latest/prop_sf/GENERATED.html

There is a workaround in Scapix using older CMake: when linking lib from another CMake file, call scapix_fix_sources(lib):

add_executable(example example.cpp)
target_link_libraries(example lib)
scapix_fix_sources(lib)

Please tell me if this workaround is good enough for your use case.

Yes, it works, thanks. But in my project I do not always build examples, so the corresponding CMake file gets skipped, scapix_fix_sources() doesn't get called, and I get the same error with add_library as described above (in my project Scapix is configured outside of the file where add_library is, just like in the example project I commited).

Is there a place where I can find any documentation about scapix_fix_sources()? If I add some new example targets into the same example/CMakeLists.txt do I call this command after each new target, or do I call it only after the last one in the file? If I add new targets linking lib in some other file do I call the command again or do I call it after all of the targets that link lib in the project are added? Can I just put it at the bottom of my top level CMake file and use it even when no other targets apart from the library is present?

Turns out there were multiple issues affecting the situation when add_library and scapix_bridge_headers are called from different directories.

I submitted a fix, and now it should work correctly with CMake 3.18 or later (there is still an issue with CMake older then 3.18).

All you need in your case is a single call to scapix_fix_sources(lib) in every CMake file where lib is used, even if it's used multiple times in the same CMake file (but there is no harm in calling it multiple times). It should work now even if all these CMake files are skipped.

I will release new Scapix version soon.

Can confirm that I no longer have these configure time errors with v1.0.34, thanks