Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generator.OutputMode.FilePerModule mode not working? #1863

Open
HenrikAkseliValve opened this issue Aug 31, 2024 · 6 comments
Open

Generator.OutputMode.FilePerModule mode not working? #1863

HenrikAkseliValve opened this issue Aug 31, 2024 · 6 comments

Comments

@HenrikAkseliValve
Copy link
Contributor

The current version of CppSharp generates only one file with Generator.OutputMode.FilePerModule mode if header files are in the same include directory. ILibrary Setup method:

        /// Setup the driver options here.
        public void Setup(Driver driver)
        {
            //Set up the driver options.
            driver.Options.GeneratorKind = GeneratorKind.CSharp;
            driver.Options.OutputDir = "<Output_folder>/QtShatpNi/QtBase";
            driver.Options.GenerationOutputMode = GenerationOutputMode.FilePerModule;
            driver.Options.GenerateDeprecatedDeclarations = false;

            // Set up parser options.
            driver.ParserOptions.LanguageVersion = CppSharp.Parser.LanguageVersion.CPP17;
            driver.ParserOptions.IncludeDirs = [@"<QT_path>\Qt\6.7.2\msvc2019_64\include", @"<QT_path>\Qt\6.7.2\msvc2019_64\include\QtCore"];

            // Set up modules.
            //AddModule(driver, "QTypeInfo", "qtypeinfo.h");
            AddModule(driver, "QChar", "qchar.h");
            AddModule(driver, "QNamespace", "qnamespace.h");
        }

        /// <summary>
        /// Helper function to generate a module.
        /// </summary>
        /// <param name="driver"></param>
        /// <param name="modulename"></param>
        /// <param name="header"></param>
        private void AddModule(Driver driver, string modulename, string header) {
            var module = driver.Options.AddModule(modulename);
            module.OutputNamespace = _namespace;
            module.Headers.Add(header);
            module.LibraryName = modulename;
            module.SharedLibraryName = "Qt6Core.dll";
            module.IncludeDirs.Add(driver.ParserOptions.IncludeDirs[1]);
        }

I think this is caused by CleanUnitPass associating unit passes with the first module with the same include path.
In the CleanUnitPass module is determined by this method:

        private Module GetModule(TranslationUnit unit)
        {
            if (unit.IsSystemHeader)
                return Options.SystemModule;

            var includeDir = Path.GetDirectoryName(unit.FilePath);
            if (string.IsNullOrWhiteSpace(includeDir))
                includeDir = ".";
            includeDir = Path.GetFullPath(includeDir);

            return Options.Modules.FirstOrDefault(
                       m => m.IncludeDirs.Any(i => Path.GetFullPath(i) == includeDir)) ??
                   Options.Modules[1];
        }

Line return Options.Modules.FirstOrDefault seem to cause the issue. I would remove CleanUnitPass class and move the module unit association to be done at the parser rather than later.

@tritao
Copy link
Collaborator

tritao commented Aug 31, 2024

Seems like we never considered this edge case, a PR with a fix is welcome, and preferably with a test.

Btw I see that you are trying to bind Qt. Are you aware of https://gitlab.com/ddobrev/QtSharp?

@HenrikAkseliValve
Copy link
Contributor Author

Yes, I'm aware of it but considering the last update date, I decided only to take influence.

@tritao
Copy link
Collaborator

tritao commented Aug 31, 2024

Yes, I'm aware of it but considering the last update date, I decided only to take influence.

Unfortunately Dimitar passed away before fully completing the work on QtSharp, but a lot of it should still be applicable.

@HenrikAkseliValve
Copy link
Contributor Author

I have been working on this.

The trouble I have right now is that current unit tests can't find C++ test header files. They should be under a subdirectory of the Executing Assembly's folder. For my case they should be under "bin/Release_x64" but they aren't.

Project files don't copy them to the bin folder because the project does not find them.
image

What is your setup @tritao? Did I forget to do something?

Test header files are in the repo but not in the folder the project tries to look for.

@tritao
Copy link
Collaborator

tritao commented Sep 17, 2024

If you check the GetTestsDirectory static inside GeneratorTests.cs, it tries to find the tests/dotnet by walking up through the directory tree.

We prefered that approach to copying the files since it should lead to less duplication and potential troubles.

I wonder why it's not picking it up on your setup though, do you have a custom output folder setup that is outside the main CppSharp checkout?

@HenrikAkseliValve
Copy link
Contributor Author

The problem was that I had a test folder in the release_x64 folder for some reason. Since the check only checks that folder structure exists not that files exist it selected it before going to the parent folder.

Thanks @tritao I missed the loop part of the GetTestsDirectory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants