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

Do not depend on both avif and avif_internal #1819

Merged
merged 6 commits into from
Dec 11, 2023

Conversation

vrabaud
Copy link
Collaborator

@vrabaud vrabaud commented Nov 29, 2023

This properly fixes #1816

In a follow-up PR, I can also move internal.h to ./src/ (or an include_private folder).

The header will still be accessed from targets if we target_include_directories them with $<TARGET_PROPERTY:avif,INCLUDE_DIRECTORIES> (which contains both public and private directories).

This will be less confusing for the user ("it's internal but is it still public?") and will enable us to split internal.h in several common-meaning headers.

@vrabaud vrabaud requested a review from wantehchang November 29, 2023 12:12
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Vincent: Thanks for writing a fix for #1816 quickly. But we should only export public functions.

@@ -89,9 +89,9 @@ typedef float (*avifTransferFunction)(float);
// and can go beyond 1.0 for HDR transfer characteristics:
// - For AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084 (PQ), the linear range is [0.0, 10000/203]
// - For AVIF_TRANSFER_CHARACTERISTICS_HLG, the linear range is [0.0, 1000/203]
avifTransferFunction avifTransferCharacteristicsGetGammaToLinearFunction(avifTransferCharacteristics atc);
AVIF_API avifTransferFunction avifTransferCharacteristicsGetGammaToLinearFunction(avifTransferCharacteristics atc);
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should not export the private functions declared in internal.h. Even though we don't provide the internal.h header to our clients, they can still call these functions if these functions are exported.

Note: In some Unix platforms (including Linux), we can give exported symbols a version (which is a string), which allows us to mark certain exported functions as private exports by using a version with "Private" in its name. But I don't think this kind of symbol versioning feature is available on Windows, and it may not even be available on all Unix platforms.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed. I went with the OBJECT library and we can now hide symbols properly, while only compiling the library once.

@vrabaud vrabaud force-pushed the avif_internal branch 5 times, most recently from 4e4b931 to 6b62f12 Compare December 1, 2023 12:17
@vrabaud vrabaud requested a review from wantehchang December 1, 2023 13:59
@vrabaud
Copy link
Collaborator Author

vrabaud commented Dec 4, 2023

@fdintino , it seems merge_static_libs does not work with generator expression. I guess there is no way around it right?

@fdintino
Copy link
Contributor

fdintino commented Dec 4, 2023

Below this line in merge_static_libs.cmake:

string(REGEX REPLACE "\\\$<BUILD_INTERFACE:([^>]*)>" "\\1" dep ${dep})

Add the line:

            string(REGEX REPLACE "\\\$<LINK_ONLY:([^>]*)>" "\\1" dep ${dep})

@vrabaud
Copy link
Collaborator Author

vrabaud commented Dec 4, 2023

Thx fdintino ! BTW, any opinion on this CL?

@fdintino
Copy link
Contributor

fdintino commented Dec 4, 2023

This all looks good to me.

Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Vincent: Thank you very much for figuring out a solution. Although I am not familiar with cmake's OBJECT libraries, your description of your solution sounds good to me. However, this does mean I don't understand some of the changes, so I also inspected the build log.

There are two problems with the current implementation. Please see my comments marked with "IMPORTANT".

@@ -42,7 +42,7 @@ endforeach()

if(AVIF_ENABLE_FUZZTEST OR AVIF_ENABLE_GTEST OR AVIF_BUILD_APPS)
add_library(aviftest_helpers OBJECT gtest/aviftest_helpers.cc)
target_link_libraries(aviftest_helpers avif_apps avif_internal)
target_link_libraries(aviftest_helpers avif_apps_internal avif_internal)
Copy link
Collaborator

@wantehchang wantehchang Dec 4, 2023

Choose a reason for hiding this comment

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

Does this mean all tests are linked with avif_internal?

Ideally, are_images_equal and the tests that only use public libavif functions should be linked with avif. But it's more important to fix the dual avif/avif_internal linking bug first.

Copy link
Collaborator Author

@vrabaud vrabaud Dec 5, 2023

Choose a reason for hiding this comment

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

Right, but as aviftest_helpers uses avif_internal, it needs to be linked to avif_apps_internal. We could also create an aviftest_helpers_internal. Or split avif.c: internal.h is only used here for AVIF_CHECKERR, AVIF_CHECRES and avifImageCopySamples. We could envision a small utils library that contains non-avif specific stuff (like the AVIF_CHECK*) and an image library that would just deal with the basic functions for images (like avifImageCopySamples) which is half of avif.c.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I discussed the aviftest_helpers issue in #1836. The use of AVIF_CHECKERR and AVIF_CHECRES in aviftest_helpers.cc can be easily avoided. And we can make avifImageCopySamples a public function.

@vrabaud vrabaud force-pushed the avif_internal branch 3 times, most recently from 1f4f6cf to 4a4d425 Compare December 5, 2023 09:35
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Vincent: I inspected the build log. This is much better

High-level comments:

  1. The position-independent code changes seem unrelated to fixing the dual avif/avif_internal linking bug.
  2. Please see the comment marked with "IMPORTANT".

CMakeLists.txt Outdated
)
target_link_libraries(avif_apps avif PNG::PNG ZLIB::ZLIB JPEG::JPEG)
set_property(TARGET avif_apps_obj PROPERTY POSITION_INDEPENDENT_CODE ON)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This change does not seem necessary.

If this is necessary or desirable, then we should also compile avifdec.c and avifenc.c as position-independent code, right?

Like my comment at line 515 above, if this change can stand alone, it is better to make this change in a separate pull request.

@vrabaud
Copy link
Collaborator Author

vrabaud commented Dec 7, 2023

I duplicated code in tests/gtest/aviftest_helpers.cc so that it does not depend on avif_internal like you requested. And only tests testing the internal API now depend on avif_internal

@vrabaud vrabaud changed the title Remove avif_internal. Do not depend on both avif and avif_internal Dec 7, 2023
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Vincent: I suggest some changes. Also please see my comment marked with "IMPORTANT" about the avif_apps and avif_apps_internal libraries.

@vrabaud vrabaud force-pushed the avif_internal branch 5 times, most recently from 7f572c9 to ba9b812 Compare December 8, 2023 23:10
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks a lot!

@@ -127,21 +127,22 @@ else()
set(XCRUN)
endif()

# This is also needed to get shared libraries (e.g. pixbufloader-avif) to compile against a static libavif.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please mention this change in the final commit message (when you squash and merge this PR), so that it is not buried in this large PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I did not add it to the CHANGELOG as it seems too minor.

} \
} while (0)
//------------------------------------------------------------------------------

Copy link
Collaborator

Choose a reason for hiding this comment

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

Delete this.

Among the files that include this header, only avifincrtest_helpers.cc uses the AVIF_CHECK* macros. But avifincrtest_helpers.cc also includes aviftest_helpers.h.

Note: Some files (e.g., avifgainmaptest.cc) include both this header and aviftest_helpers.h. I am surprised that compilers allow duplicate macro definitions. I guess if the definitions are exactly the same, then they are allowed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed, that's how C works: you are allowed to redefine the macro as long as it is the same:

Now define avif_obj on which avif and avif_internal depend.
There is only one compilation happening. Only symbol export is
different between the two libs
@vrabaud vrabaud merged commit 7b9a072 into AOMediaCodec:main Dec 11, 2023
@vrabaud vrabaud deleted the avif_internal branch December 11, 2023 11:52
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

Successfully merging this pull request may close these issues.

are_images_equal and many tests are linked with both libavif and libavif_internal
3 participants