Skip to content

CMake cleanup #7658

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

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open

CMake cleanup #7658

wants to merge 22 commits into from

Conversation

pfultz2
Copy link
Contributor

@pfultz2 pfultz2 commented Jul 9, 2025

This removes the object libraries and uses normal cmake targets. This helps simplifies a lot of the cmake since we can properly propagate usage requirements.

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 9, 2025

Because of the global registration an object library will need to be used for at least cppcheck-core, but we can still wrap it in an interface library so it can propagate usage requirements though.

@firewave
Copy link
Collaborator

firewave commented Jul 9, 2025

Using interface libraries would be an acceptable modernization (although I personally detest them - I had to many problems with them in the past). We need to test though that things work with the currently specified minimum CMake version and raise it appropriately if necessary.

But if we actually want to support shared libraries there is a lot of work to be done:

  • visibility handling on non-Windows platforms
  • needs to add annotation to all exported symbols (currently it was only set for the ones actually used in tests)
  • needs ABI handling/versioning for the shared objects
  • adjust the install targets
  • adjust the shipped Visual Studio project to generate the same output files
  • adjust the Windows installer
  • CI jobs to test this on all platforms
  • ... possibly even more things I cannot think off the top of my head

And IMO externals should not be shared libraries.

Also we still have static objects in our code which possibly makes the proper usage of the shared objects impossible. Beside that I reckon there never was and never will be a single user of the shared objects. And the current implementation was only partial.

We should not be supporting shared libraries at all because it just causes more work now and in the future and I do not see any upsides at all. We should be removing features instead of adding and simplifying things instead of making them even more complex (with latter I am referring to the support matrix - not the code).

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 9, 2025

The purpose of the shared libraries would only be for local dev. I wouldn't envision us installing them.

@firewave
Copy link
Collaborator

firewave commented Jul 9, 2025

The purpose of the shared libraries would only be for local dev.

Please elaborate. I do not see how it would be of any use - especially given that it was never available and nobody complained. And if we want to support that we need to test it i.e. CI workflows. Otherwise it is just more stuff which rots away in this repo.

I wouldn't envision us installing them.

It would be possible but it would not work - so it should not be allowed.

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 9, 2025

So with this change there is new -Wsuggest-attribute=noreturn warnings. I am not sure why we didnt warn before. I dont see us disabling warnings. Do you know why?

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 9, 2025

Please elaborate. I do not see how it would be of any use

Faster linking time.

target_include_directories(tinyxml2 SYSTEM PUBLIC .)
target_include_directories(tinyxml2 PUBLIC .)
Copy link
Collaborator

@firewave firewave Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That flag needs to depend on the EXTERNALS_AS_SYSTEM option.

Comment on lines 73 to 75
# if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
# target_precompile_headers(cppcheck-core-private PRIVATE precompiled.h)
# endif()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be enabled again before merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, that was to test the CI. I was getting error:

../../../lib/CMakeFiles/cppcheck-core-private.dir/cmake_pch.hxx.gch: file not recognized: file format not recognized

Now with it disabled I get an error that there isnt a make rule for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, you are explicitly building it in selfcheck, but its using the wrong target name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching to the OBJECT library directly fixed this issue.

if (BUILD_CORE_DLL)
target_compile_definitions(tinyxml2_objs PRIVATE TINYXML2_EXPORT)
endif()
add_library(tinyxml2 ${srcs} ${hdrs})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be able to become a shared library.

if (BUILD_CORE_DLL)
target_compile_definitions(simplecpp_objs PRIVATE SIMPLECPP_EXPORT)
endif()
add_library(simplecpp ${srcs} ${hdrs})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be able to become a shared library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will if we set BUILD_SHARED_LIBS.

add_library(frontend OBJECT ${hdrs} ${srcs})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this can become a shared library (which it shouldn't) it also needs the import/export handling. This is getting way more complicating than the existing code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this can become a shared library (which it shouldn't) it also needs the import/export handling.

Only on windows is that needed. Either way the purpose of this PR is not to support shared libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this comment, this library shouldn't be an object library. I am not sure why its working.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why this works. Since cmake 3.12, object libraries can be linked directly instead of adding the $<TARGET_OBJECTS> to the sources. This will make it simpler.

@firewave
Copy link
Collaborator

Faster linking time.

Yes, that probably will save a few microseconds...

Unlike the precompiled headers you just disabled which will actually save a lot of compilation time...

So with this change there is new -Wsuggest-attribute=noreturn warnings. I am not sure why we didnt warn before. I dont see us disabling warnings. Do you know why?

How do these occur? I did not see them in the CI failures.

const int res = pclose(p);
int res = pclose(p);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes (among others) in macos-15 builds:

/Users/runner/work/cppcheck/cppcheck/cli/cppcheckexecutor.cpp:746:9: warning: cast from 'const int *' to 'int *' drops const qualifier [-Wcast-qual]
  746 |     if (WIFEXITED(res)) {
      |         ^
/Applications/Xcode_16.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/wait.h:152:26: note: expanded from macro 'WIFEXITED'
  152 | #define WIFEXITED(x)    (_WSTATUS(x) == 0)
      |                          ^

Failing builds on warnings is tracked via https://trac.cppcheck.net/ticket/12021.

Copy link
Contributor Author

@pfultz2 pfultz2 Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its needed to fix CI, because they became errors in the CI with these changes. I am not sure why it didnt error out before in the CI.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope is getting way too big with a lot of questionable sidecar changes. This needs to be fixed more incrementally.

Its needed to fix CI, because they became errors in the CI with these changes. I am not sure why it didnt error out before in the CI.

That should not be happening. That indicates that something is wrong in these CMake change.

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 11, 2025

@firewave Alright, I think this is ready to go. This will fix the issue with using boost(#7655 is still needed if we want to disable boost).

@pfultz2 pfultz2 requested a review from firewave July 11, 2025 13:51
@firewave firewave added the merge-after-next-release Wait with merging this PR until after the next Release label Jul 14, 2025
@firewave
Copy link
Collaborator

@firewave Alright, I think this is ready to go. This will fix the issue with using boost(#7655 is still needed if we want to disable boost).

There's several things which do not look right to me. I am not feeling very well right now so it will take quite a while for me to review and even understand what this is doing since the changes are hard to follow.

Also the proper fixes for the boost issues should be merged as since those will have actual tests for the behavior changes.

@pfultz2
Copy link
Contributor Author

pfultz2 commented Jul 14, 2025

There's several things which do not look right to me. I am not feeling very well right now so it will take quite a while for me to review and even understand what this is doing since the changes are hard to follow.

Hope you feel better soon. Here is a summary/explanation of the changes which hopefully can help you review the PR.

The biggest change is to move all the usage requirements into the target and link with target directly instead of using $<TARGET_OBJECTS> and manually adding it for each consumer. So writing target_link_libraries(someTarget cppcheck-core) it will link with cppcheck-core and add any headers or defines that are need to use cppcheck-core.

So now I removed the manual includes and linking, and just link a single target directly. I did this based on the includes in the cmake, but I didnt check the source code if its actually including headers from the component. In the future, we can probably do some more cleanup up here. I dont think every component that is linking simplecpp is using headers from simplecpp, but I didnt check the c++ source files and added it as it was being included in the cmake.

For tinyxml2, I created a target even when we are using an external tinyxml2. So we just need to link the tinyxml2 and no longer to check if its external and link something else.

The cppcheck-core will still be an object library when BUILD_SHARED_LIBS=Off because of the auto-registration of the checks. I realized later that object libraries can now be linked starting in cmake 3.12, which means object libraries can still propagate usage requirements as well. In the future, we could consider making other libraries OBJECT as well.

Supporting BUILD_SHARED_LIBS=On is beyond the scope of this PR, but I did test this on non-windows and it does work. To support this on windows, will probably just need some small tweaks to support(such as setting WINDOWS_EXPORT_ALL_SYMBOLS property or using an object library), but all these could be addressed in the future if the need arises.

In some places, we were using a couple of source files from another component and rebuilding them again(like filelister.cpp). Instead, I just link the component that builds that source file instead of doing these kind of hacks. If we want to make a subset of source files a seperate component then we could refactor that in the future. I dont do that here since I want to minimize the changes here, but it is something we can address in the future.

As such, the dmake exe needs the cli lib to be built. So we still build the cli lib even when BUILD_CLI=Off, but we wont build a cppcheck executable. I am not sure what the usecase is for BUILD_CLI=Off is, but if its just to build less when using the gui, we can work on improving this in the future in order to minimize the changes here.

@pfultz2
Copy link
Contributor Author

pfultz2 commented Aug 11, 2025

@firewave Are you able to review this?

Copy link

@firewave
Copy link
Collaborator

@firewave Are you able to review this?

Thanks for the extensive description.

I will take another look at this soon - need to take care of things which piled up in the past few weeks.

The first time I looked at this I saw some different shortcomings in the existing code which need to be singled out/addressed first but I cannot remember what it was.

My aim is to have this resolved in this dev cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-after-next-release Wait with merging this PR until after the next Release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants