-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Open
Description
Description
Summary
When building the yogacore library with the default CMakeLists.txt in the yoga/ directory, the debug/AssertFatal.cpp file (which defines facebook::yoga::fatalWithMessage) is not included in the source list when using file(GLOB ...). This doesn’t affect the static build (libyogacore.a) in my current test suite, but it causes a linker error (undefined reference to facebook::yoga::fatalWithMessage) when building as a shared library (libyogacore.so).
Steps to Reproduce
- Modify
yoga/CMakeLists.txtto support shared libraries:option(BUILD_SHARED_LIBS "Build yogacore as a shared library" OFF) if(BUILD_SHARED_LIBS) add_library(yogacore SHARED ${SOURCES}) else() add_library(yogacore STATIC ${SOURCES}) endif()
- Run CMake with shared library enabled:
cmake -B build -S . -DBUILD_SHARED_LIBS=ON make -j$(nproc)
- Observe the linker error during the
yogatestsbuild:/usr/bin/ld: CMakeFiles/yogatests.dir/StyleTest.cpp.o: in function `facebook::yoga::Style::computeMargin(...)`: StyleTest.cpp:(.text...): undefined reference to `facebook::yoga::fatalWithMessage(char const*)`
Expected Behavior
- The
yogacorelibrary (static or shared) should include all necessary source files, includingdebug/AssertFatal.cpp, so thatfatalWithMessageis defined and the build completes successfully.
Actual Behavior
- The original
file(GLOB SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/**/*.cpp)does not includedebug/AssertFatal.cpp. - Static builds succeed due to linker laziness (if
fatalWithMessageisn’t called), but shared builds fail with anundefined referenceerror because the symbol is referenced inStyleTest.cpp(viaStyle.h).
Root Cause
- The
file(GLOB ...)pattern inyoga/CMakeLists.txtfails to recurse into thedebug/subdirectory, omittingdebug/AssertFatal.cpp. This is unexpected since/**/*.cppshould include subdirectories, but it doesn’t work as intended in my environment (CMake 3.26, Fedora).
My Fix
I modified yoga/CMakeLists.txt to use file(GLOB_RECURSE ...) instead:
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)This correctly includes debug/AssertFatal.cpp, and both static and shared builds succeed:
cmake -B build -S . -DBUILD_SHARED_LIBS=ON # Works
cmake -B build -S . -DBUILD_SHARED_LIBS=OFF # Works
make -j$(nproc)Suggested Action
- Update
yoga/CMakeLists.txtto usefile(GLOB_RECURSE ...)or explicitly includedebug/AssertFatal.cppto ensure all necessary sources are built intoyogacore. - Alternatively, clarify in the documentation if
debug/AssertFatal.cppis intentionally excluded and how users should handle shared library builds.
Environment
- OS: Fedora 41
- CMake Version: 3.26
- Compiler: GCC
- Yoga Version: 3.2.1
Additional Notes
- The static build’s success seems to rely on the linker not needing
fatalWithMessagein my test suite. If tests or consumers call it (e.g., viaStyle.h), the static build could fail too. - Full modified
CMakeLists.txt:cmake_minimum_required(VERSION 3.13...3.26) project(yogacore) set(CMAKE_VERBOSE_MAKEFILE on) if(TARGET yogacore) return() endif() include(CheckIPOSupported) option(BUILD_SHARED_LIBS "Build yogacore as a shared library" OFF) set(YOGA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..) include(${YOGA_ROOT}/cmake/project-defaults.cmake) file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) if(BUILD_SHARED_LIBS) add_library(yogacore SHARED ${SOURCES}) else() add_library(yogacore STATIC ${SOURCES}) endif() if(ANDROID) target_link_libraries(yogacore log) endif() check_ipo_supported(RESULT result) if(result) set_target_properties(yogacore PROPERTIES CMAKE_INTERPROCEDURAL_OPTIMIZATION true) endif() target_include_directories(yogacore PUBLIC $<BUILD_INTERFACE:${YOGA_ROOT}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/yoga>)
jwosty
Metadata
Metadata
Assignees
Labels
No labels