Skip to content

build error on Apple MacOs with M3 #24

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

Closed
noondie opened this issue Apr 6, 2024 · 21 comments
Closed

build error on Apple MacOs with M3 #24

noondie opened this issue Apr 6, 2024 · 21 comments
Assignees
Labels
bug Something isn't working macos

Comments

@noondie
Copy link

noondie commented Apr 6, 2024

Hello
first I want to say a big thank you for your article and all those explanations.

I tried to compile your code as described in the QuickStart doc.

#cmake -GXcode -DCMAKE_BUILD_TYPE=Release -B build/Xcode

and
cmake --build build/xcode

and got the following error
clang: error: no such file or directory: 'x86_64/TestRunner.o'
which is correct ;=)

where can I specify the correct platform? And why is the platform wrong estimated?

thanks for your help

@noondie
Copy link
Author

noondie commented Apr 6, 2024

add some more info
arm64 is found. Any idea, why the x86_64 folder will be used?

Ld /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/ResourcesTest.build/Debug/Objects-normal/arm64/Binary/ResourcesTest normal arm64 (in target 'ResourcesTest' from project 'BasicGuiProjectSetup')
cd /Users/conrad/Sources/cpp-gui-template-sdl2
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -Xlinker -reproducible -target arm64-apple-macos14.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -O0 -L/Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/EagerLinkingTBDs/Debug -L/Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/src/core/Tests/Debug -F/Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/EagerLinkingTBDs/Debug -F/Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/src/core/Tests/Debug -filelist /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/ResourcesTest.build/Debug/Objects-normal/arm64/ResourcesTest.LinkFileList -Xlinker -rpath -Xlinker /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/_deps/sdl2-build/Debug -Xlinker -object_path_lto -Xlinker /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/ResourcesTest.build/Debug/Objects-normal/arm64/ResourcesTest_lto.o -Xlinker -no_deduplicate -Wl,-search_paths_first -Wl,-headerpad_max_install_names /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/TestRunner.build/Debug/Objects-normal/arm64 x86_64/TestRunner.o /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/src/core/Debug/libCore.a /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/_deps/spdlog-build/Debug/libspdlogd.a /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/_deps/fmt-build/Debug/libfmtd.a /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/vendor/imgui-setup/Debug/libimgui.a /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/_deps/sdl2-build/Debug/libSDL2-2.0d.0.dylib /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/src/settings/Debug/libSettings.a -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/ResourcesTest.build/Debug/Objects-normal/arm64/ResourcesTest_dependency_info.dat -o /Users/conrad/Sources/cpp-gui-template-sdl2/build/xcode/build/ResourcesTest.build/Debug/Objects-normal/arm64/Binary/ResourcesTest
clang: error: no such file or directory: 'x86_64/TestRunner.o'

@noondie
Copy link
Author

noondie commented Apr 6, 2024

in the next step I tried
% cmake -DCMAKE_BUILD_TYPE=Release -B build/xcode
% cmake --build build/xcode
which compiled fine

after that
% cpack --config build/xcode/CPackConfig.cmake

which build the dmg file , but the icon in the install process is broken.
I guess this is because after installation the App into the Application folder, I get an error when executing.
"You cannot open the Program App since it is damaged or incomplete"

this is the folder struct

% pwd
/Applications/App.app
% tree
.
└── Contents
├── Frameworks
│   └── libSDL2-2.0.0.dylib
├── Info.plist
├── MacOS
│   └── App
└── Resources
├── Manrope.ttf
└── icon.icns

if I execute App, the app start running.

@MartinHelmut
Copy link
Owner

MartinHelmut commented Apr 8, 2024

Hey and thanks for reporting! I'll try to replicate what you have. Do I assume right you did all over the a terminal, e.g. iTerm? Could you also post your CMake and XCode version for me as reference?

@MartinHelmut MartinHelmut added bug Something isn't working macos labels Apr 8, 2024
@noondie
Copy link
Author

noondie commented Apr 8, 2024 via email

@MartinHelmut
Copy link
Owner

Thanks for adding the used versions! I was able to reproduce the issue and created a first PR where I try to solve the problem. One part is the defined architecture. I reworked this part for macOS to be defined more explicit.

The current TL;DR is:

  • Changed CMAKE_OSX_ARCHITECTURES to be a cache variable
  • Specified x86_64;arm64 (universal executable) as default value for presets

Long form:

By having the CMAKE_OSX_ARCHITECTURES variable a cache variable it can be overridden on command usage with the desired target Apple architecture. For example, for a universal executable the value x86_64;arm64 should be used. Making the command a bit longer, but more explicit:

cmake -GXcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -B build/xcode
cmake --build build/xcode

The issue with this is I cannot run CPack yet!1 Still investigating, because it works with presets (read further).

I also defined creating universal executables via presets. This gives a very convenient command I'll probably take into the quick start guide documentation.2

cmake --preset xcode-release
cmake --build --preset xcode-release

The actual distribution can then be created without problems (at least for me) with the defined Xcode CPack preset:

cpack --preset xcode-release

Or, thanks to CMake workflows, all of this, after a fresh clone, works with one command:

cmake --workflow --preset xcode-dist

Let me know if you can run the preset commands, e.g. the workflow version of it (after removing the build folder first for a fresh run).

Footnotes

  1. For some reason when I run the commands separately, not as presets, even with CMAKE_BUILD_TYPE defined as Release, I get always a Debug folder from Xcode.

  2. I will also need to update all other template repos and the article 😅

@MartinHelmut MartinHelmut self-assigned this Apr 8, 2024
@MartinHelmut
Copy link
Owner

Found out why CPack with the base command did not work, but with the Preset did: For Xcode to pick a Release configuration it is necessary to pass --config Release on build, like this:

cmake -GXcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -B build/xcode
cmake --build build/xcode -- config Release

Only then can CPack be run successfully, finding the right folder for the release distribution:

cpack --config build/xcode/CPackConfig.cmake

I also updated the PR: #25 I plan to merge the PR only after I tested some more scenarios in Windows and Linux as well, just to be sure how this option and the usage of presets can influence results on the other platforms.

@noondie
Copy link
Author

noondie commented Apr 8, 2024 via email

@MartinHelmut
Copy link
Owner

Hey, yes, as I wrote:

for a universal executable the value x86_64;arm64 should be used ...

So either using this on the command line, or using the preset command where this is the default.

Does everything run now for you?

@noondie
Copy link
Author

noondie commented Apr 9, 2024 via email

@MartinHelmut
Copy link
Owner

Unfortunately i have to disable the test build otherwise i will get an compile error

Can you post some more details about this? E.g. the error output? Would love to see what the issue is with that :)

Regarding subfolder: I think this should be possible via MACOSX_PACKAGE_LOCATION as used in the AppAsset.cmake file. Here you could probably define the set of source files you want to differentiate and set the target property on them.

# Split different types of assets
set(FONT_ASSETS ${PROJECT_SOURCE_DIR}/src/assets/fonts/Manrope.ttf)
set(IMAGE_ASSETS
  ${PROJECT_SOURCE_DIR}/src/assets/images/img1.png
  ${PROJECT_SOURCE_DIR}/src/assets/images/img2.png)

# Platform specific static assets
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
  # ...
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  set(MACOSX_ICON_ASSET ${PROJECT_SOURCE_DIR}/src/assets/icons/icon.icns)
  set(ALL_MACOSX_STATIC_ASSETS
    ${FONT_ASSETS}
    ${IMAGE_ASSETS}
    ${MACOSX_ICON_ASSET})

  # Define subfolders here:
  set_source_files_properties(${MACOSX_ICON_ASSET}
    PROPERTIES MACOSX_PACKAGE_LOCATION ${CMAKE_INSTALL_DATADIR})
  set_source_files_properties(${FONT_ASSETS}
    PROPERTIES MACOSX_PACKAGE_LOCATION ${CMAKE_INSTALL_DATADIR}/fonts)
  set_source_files_properties(${IMAGE_ASSETS}
    PROPERTIES MACOSX_PACKAGE_LOCATION ${CMAKE_INSTALL_DATADIR}/images)

  target_sources(${NAME} PUBLIC ${ALL_MACOSX_STATIC_ASSETS})
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
  # ...
endif ()

Remark: I did not test this, but I think this is how it should work.

@noondie
Copy link
Author

noondie commented Apr 14, 2024 via email

@MartinHelmut
Copy link
Owner

Hey 👋🏻

Issue 1 - Build issue

Let's start with this one. The build error I can reproduce, reason is, as described in the docs, when not using CMake Presets the target architecture needs to be set explicitly via CMAKE_OSX_ARCHITECTURES on macOS, e.g. for universal builds to x86_64;arm64:

cmake -GXcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -B build/xcode
cmake --build build/xcode --config Release

Issue 2 - Bundle structure

I actually cannot reproduce your folder structure when running CPack. One thing that is very strange to me:

as you see, there is a share folder

A share folder should only be created at Windows or Linux, not macOS, where it should be a Resources folder. So this is really confusing to me, as if the environment is wrongly detected by CMake 🤔 Could you give me the full log for all three commands (ref) to create a bundle?

cmake -GXcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -B build/xcode
cmake --build build/xcode --config Release
cpack --config build/xcode/CPackConfig.cmake

This should help me figuring out what is going on on your end.

@noondie
Copy link
Author

noondie commented Apr 14, 2024 via email

@MartinHelmut
Copy link
Owner

Ahh yes I see, the package location needs to specify the installation data directory by using CMAKE_INSTALL_DATADIR:

set_source_files_properties("<files ...>"
  PROPERTIES MACOSX_PACKAGE_LOCATION ${CMAKE_INSTALL_DATADIR}/images)

So instead of using share/images it would be ${CMAKE_INSTALL_DATADIR}/images to create a Resources/images folder in the app bundle.

@noondie
Copy link
Author

noondie commented Apr 14, 2024 via email

@MartinHelmut
Copy link
Owner

Alright, I had to understand what is going on 😅 But, I think I figured it out now. I'll start with a short version.

TL;DR

No need to set(CMAKE_INSTALL_DATADIR "Resources"). Two things needed, first, remove the RESOURCE property from the target properties for macOS:

set_target_properties(${NAME} PROPERTIES
  XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
  MACOSX_BUNDLE_BUNDLE_VERSION "${BUILD_VERSION}"
  MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
  MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Manifests/Info.plist"
  MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_COMPANY_NAMESPACE}.${CMAKE_PROJECT_NAME}"
  MACOSX_BUNDLE_COPYRIGHT "(c) ${CURR_YEAR} ${PROJECT_COMPANY_NAME}"
  INSTALL_RPATH @executable_path/../Frameworks
-  RESOURCE "${MACOSX_STATIC_ASSETS}")
+ )

Second, do not use CMAKE_INSTALL_DATADIR and define the folder directly, as relative path (as it is relative to the app bundle):

set_source_files_properties("<files ...>"
  PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/images")

Long explanation

I was able to reproduce the same behaviour, getting a share folder. But only under the condition I remove the RESOURCE property from set_target_properties in src/app/cmake/packaging/Darwin.cmake:

set_target_properties(${NAME} PROPERTIES
  XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
  MACOSX_BUNDLE_BUNDLE_VERSION "${BUILD_VERSION}"
  MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
  MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Manifests/Info.plist"
  MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_COMPANY_NAMESPACE}.${CMAKE_PROJECT_NAME}"
  MACOSX_BUNDLE_COPYRIGHT "(c) ${CURR_YEAR} ${PROJECT_COMPANY_NAME}"
  INSTALL_RPATH @executable_path/../Frameworks
-  RESOURCE "${MACOSX_STATIC_ASSETS}")
+ )

Removing this property yielded the share folder using any version of:

set_source_files_properties("<files ...>"
  PROPERTIES MACOSX_PACKAGE_LOCATION ${CMAKE_INSTALL_DATADIR}/images)

Looking at the documentation for GNUInstallDirs, this should have not surprised me. As DATADIR points to DATAROOTDIR that is indeed the value share. This only never became an issue for me as the RESOURCE property moved assets into the Resources folder in a flat structure. Also, CMAKE_INSTALL_DATADIR is a cache variable. If it was set to a different value it will keep the value, even if the set call is removed later. It only changes then when removing the build folder proper, and re-running the commands.

The problem then is, it is either the RESOURCE property for the macOS target, or setting file properties directly via set_source_files_properties to actually create a dedicated folder structures. Doing this, removing the RESOURCE property in src/app/cmake/packaging/Darwin.cmake, and then using set_source_files_properties with a relative path, will give the desired result. Important is then to not use the CMAKE_INSTALL_DATADIR, but define Resources directly.

Picking up the earlier example this could look like this:

# Split different types of assets
set(FONT_ASSETS ${PROJECT_SOURCE_DIR}/src/assets/fonts/Manrope.ttf)
set(IMAGE_ASSETS
  ${PROJECT_SOURCE_DIR}/src/assets/images/img1.png
  ${PROJECT_SOURCE_DIR}/src/assets/images/img2.png)

# Platform specific static assets
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
  # ...
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  set(MACOSX_ICON_ASSET ${PROJECT_SOURCE_DIR}/src/assets/icons/icon.icns)
  set(ALL_MACOSX_STATIC_ASSETS
    ${FONT_ASSETS}
    ${IMAGE_ASSETS}
    ${MACOSX_ICON_ASSET})

  # Define subfolders here:
  set_source_files_properties(${MACOSX_ICON_ASSET}
    PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
  set_source_files_properties(${FONT_ASSETS}
    PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/fonts")
  set_source_files_properties(${IMAGE_ASSETS}
    PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/images")

  target_sources(${NAME} PUBLIC ${ALL_MACOSX_STATIC_ASSETS})
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
  # ...
endif ()

Small note, if changing the folder for the font this also needs to be adjusted in src/core/Core/Application.cpp:

- const std::string font_path{Resources::font_path("Manrope.ttf").generic_string()};
+ const std::string font_path{Resources::font_path("fonts/Manrope.ttf").generic_string()};

@noondie
Copy link
Author

noondie commented Apr 19, 2024 via email

@MartinHelmut
Copy link
Owner

cmake is really a tough guy

It is indeed 😅 But also fun to tackle! Glad I was able to help. In that case I would close this issue now as resolved ✌🏻 Don't hesitate to reach out again, I can also always reopen this issue if there comes up anything else.

@noondie
Copy link
Author

noondie commented Apr 21, 2024 via email

@MartinHelmut
Copy link
Owner

Have you ever tried to do this with iOS?

Yes indeed 😅 I'm literally currently (last week's) working on getting the template ready for mobile devices in general. I started with SDL3 version and am testing it currently. After that I will port it to this and other templates too.

@noondie
Copy link
Author

noondie commented Apr 21, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working macos
Projects
None yet
Development

No branches or pull requests

2 participants