0

I'm on MacOS and I'm coding a C++ project using SDL2 containing a src file main.cpp, a spritesheet.png and a .txt file.

They're all in the same "src" directory.

When I compile and run my program from the terminal with g++, it runs smoothly, no issues, the image is rendered and the text file is open and read.

Now, I am new with CMake and I'm just starting to understand the very basic but when I use CMake to create a .app and compile my code:

set_target_properties(myApp PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_FRAMEWORK_IDENTIFIER org.cmake.ExecutableTarget
RESOURCE "${RESOURCE_FILES}")

the image and the .txt files are put into the "Resources" folder and the .exe goes in the MacOS folder.

When I run my .app, the image is displayed but the .txt cannot be opened.

I have tried to use in my CMakeLists.txt the following command which copies my .txt file in the same dir as my final .unix exe file (in the MacOS folder of my .app) rather than putting it in the "Resources" dir:

add_custom_command(TARGET myApp POST_BUILD
               COMMAND ${CMAKE_COMMAND} -E copy
               ${CMAKE_CURRENT_SOURCE_DIR}/lazy.txt  $<TARGET_FILE_DIR:myApp>)

But my .txt still does not open when running my .app file.

In my code, the path for the .txt file is "lazy.txt" (as the .txt file is in the same dir as main.cpp)

Could this just be due to the path in the src code or am I missing something else here?

Valentin
  • 39
  • 5
  • Try copying the .txt file into the same dir as the executable - and see if it works? – FreudianSlip Apr 21 '22 at 16:01
  • @FreudianSlip I did that and the .txt file does not open – Valentin Apr 21 '22 at 16:04
  • 1
    Add a line in your code to print the working directory. Then use that to figure out the relative path to your text file. – L. Scott Johnson Apr 21 '22 at 16:05
  • The location of the working directory will depend on the IDE or method you are running your code. For example on windows using Visual Studio 2019 the working directory is set by default (you can change) to a VS IDE variable $(ProjectDir) which is the location of the VS project file for the executable target. This is usually where the source is located. However for the same executable if you launch from the OS file browser the working directory then becomes the same folder as the executable which is not the same as the $(ProjectDir) – drescherjm Apr 21 '22 at 16:13
  • @L.ScottJohnson it says my working dir is Users/MYUSERNAME.... I don't get why my image opens when it's path in the code is in the same dir as my .txt file. – Valentin Apr 21 '22 at 16:35
  • ***I don't get why my image opens when it's path in the code is in the same dir as my .txt file*** You would have to show the code for the image viewing to possibly figure out why it does that. That is not normal or expected behavior for it to do that. In c++ you normally have to give the code the correct folder either an absolute path or one that is relative to the current working directory. No searching of other folders happens unless you write code to do so. – drescherjm Apr 21 '22 at 16:39
  • @drescherjm thanks, how can I set my program working directory to be the one where the .exe file is? – Valentin Apr 21 '22 at 16:52
  • I am not a macOS expert and you have not mentioned your IDE yet. You can't do this with a CMake script. The working directory depends on where and how you are executing your code. – drescherjm Apr 21 '22 at 16:53
  • @drescherjm I'm using either Vim and compile from Terminal and it works. Or using CodeRunner4 and it works too. Only when using CMake from Terminal and building my .app then I'm not able to have it function properly. – Valentin Apr 21 '22 at 17:00
  • UPDATE: I made it work by inputting in the code the full path of the .txt file on my computer however I want my program to use a path relative to the final build (as it already does for my images...) – Valentin Apr 21 '22 at 17:08
  • `argv[0]` should give you access to the file name of the exe, so `std::filesystem::path filePath = ...; if (!filePath.is_absolute()) { std::filepath::path p = absolute(std::filesystem::path(argv[0])); p.swap(filePath); filePath += p; }` should provide you with the absolute path in `filePath`. Note that with this behaviour you'll be inconsistent with every other command line tool though. If your program installation comes with several data files, the user shouldn't have to manually enter the exact file name imho. – fabian Apr 21 '22 at 17:41

1 Answers1

0

I've found the solution to my problem in another post on StackOverflow, it is using the CoreFoundation CFURL functions to locate a file in a MacOS app bundle: Accessing files in resources folder in mac osx app bundle

Valentin
  • 39
  • 5