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

Windows build: release overwrites debug files #45

Closed
Jagholin opened this Issue Apr 7, 2014 · 8 comments

Comments

2 participants
@Jagholin

Jagholin commented Apr 7, 2014

Hallo,

I tried to find answer to this in the documantation, with no immediate success:

Im trying to build magnum library for use with VS2013 in release as well as in debug modes. It seems however that output files have same names, and overwrite each other on install. Additionaly, cmake modules don't care to differentiate between release/debug versions of binaries either.

This is however important, as release/debug modules are not compatible, for example, you can't link magnum's release binaries with corrade's debug ones(error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL', error LNK2038: mismatch detected for 'RuntimeLibrary' is a direct result of such an attempt).

Exactly the same issue happens in custom programs that link to magnum: one can only build either debug or release, depending on what corrade/magnum configuration was recently built

@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Apr 7, 2014

Owner

Hi, thanks for the detailed report, now I finally understand why this is needed. Personally, on Linux, I did not come across such linking issues, thus I did not have any need for distinction between debug and release libs.

Related to #20.

Owner

mosra commented Apr 7, 2014

Hi, thanks for the detailed report, now I finally understand why this is needed. Personally, on Linux, I did not come across such linking issues, thus I did not have any need for distinction between debug and release libs.

Related to #20.

@mosra mosra added the buildsystem label Apr 7, 2014

@mosra mosra self-assigned this Apr 7, 2014

@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Apr 9, 2014

Owner

Done in 1e6e4c3 and 5101e3a and similarly also in Corrade and other projects. Debug libraries are installed with -d suffix, plugins are slightly more complicated, but hopefully I explained it in the docs clearly enough :-) As with all other build system changes, you need to update FindCorrade.cmake and FindMagnum.cmake CMake modules in your projects in order to properly find the renamed libraries. Other than that, from user perspective the usage is still the same and everything is done automagically by CMake behind the scenes.

These changes are now also merged into compatibility branch to make them usable with MSVC. I did some testing and the debug/release distinction seems to work flawlessly, please report if you find any issues.

Owner

mosra commented Apr 9, 2014

Done in 1e6e4c3 and 5101e3a and similarly also in Corrade and other projects. Debug libraries are installed with -d suffix, plugins are slightly more complicated, but hopefully I explained it in the docs clearly enough :-) As with all other build system changes, you need to update FindCorrade.cmake and FindMagnum.cmake CMake modules in your projects in order to properly find the renamed libraries. Other than that, from user perspective the usage is still the same and everything is done automagically by CMake behind the scenes.

These changes are now also merged into compatibility branch to make them usable with MSVC. I did some testing and the debug/release distinction seems to work flawlessly, please report if you find any issues.

@Jagholin

This comment has been minimized.

Show comment
Hide comment
@Jagholin

Jagholin Apr 10, 2014

Thanks it now seems to work.

Although i still had a problem while doing "textured triangle" tutorial: configure.h was generated only once at the beginning, so MAGNUM_PLUGINS_DIR define always pointed to the same directory. I think it would be better to write both release and debug plugin directories to the configure.h file and choose one of them via C preprocessor.

Jagholin commented Apr 10, 2014

Thanks it now seems to work.

Although i still had a problem while doing "textured triangle" tutorial: configure.h was generated only once at the beginning, so MAGNUM_PLUGINS_DIR define always pointed to the same directory. I think it would be better to write both release and debug plugin directories to the configure.h file and choose one of them via C preprocessor.

@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Apr 10, 2014

Owner

Yeah, dynamic plugins are still an issue, I failed to find any acceptable solution. The easiest (but still annoying) one is to specify the plugin directory at runtime (e.g. via command-line parameter).

The problem is (as far as I know) that CMake by default doesn't provide any usable information which could be handled via preprocessor -- the CMAKE_INTDIR preprocessor token (which, to make everything even worse, is defined only when Visual Studio or XCode is used) is set to string containing "Debug" or "Release", thus I would still need to decide on it at runtime, which is definitely not something I would want to have in example code:

#ifdef CMAKE_INTDIR
std::string pluginDir;
if(std::string{CMAKE_INTDIR}.find("Debug") != std::string::npos)
    pluginDir = MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR;
else
    pluginDir = MAGNUM_PLUGINS_IMPORTER_RELEASE_DIR;
#else
const std::string pluginDir{MAGNUM_PLUGINS_IMPORTER_DIR};
#endif

I'll try to look deeper into this, maybe it would be possible to create some CMake macro which would produce actually usable preprocessor information.

Owner

mosra commented Apr 10, 2014

Yeah, dynamic plugins are still an issue, I failed to find any acceptable solution. The easiest (but still annoying) one is to specify the plugin directory at runtime (e.g. via command-line parameter).

The problem is (as far as I know) that CMake by default doesn't provide any usable information which could be handled via preprocessor -- the CMAKE_INTDIR preprocessor token (which, to make everything even worse, is defined only when Visual Studio or XCode is used) is set to string containing "Debug" or "Release", thus I would still need to decide on it at runtime, which is definitely not something I would want to have in example code:

#ifdef CMAKE_INTDIR
std::string pluginDir;
if(std::string{CMAKE_INTDIR}.find("Debug") != std::string::npos)
    pluginDir = MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR;
else
    pluginDir = MAGNUM_PLUGINS_IMPORTER_RELEASE_DIR;
#else
const std::string pluginDir{MAGNUM_PLUGINS_IMPORTER_DIR};
#endif

I'll try to look deeper into this, maybe it would be possible to create some CMake macro which would produce actually usable preprocessor information.

@mosra mosra reopened this Apr 10, 2014

@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Apr 10, 2014

Owner

Oh, apparently there is COMPILE_DEFINITIONS_<CONFIG> per-target property, which could be used to do exactly what we need, in a cross-platform way:

add_executable(myexe main.cpp)
set_target_properties(myexe PROPERTIES COMPILE_DEFINITIONS_DEBUG "-DOH_YEAH_WE_HAVE_DEBUG_BUILD")

and then, as you suggested, in the configuration file decide about that using preprocessor:

#ifdef OH_YEAH_WE_HAVE_DEBUG_BUILD
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}"
#else
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_RELEASE_DIR}"
#endif

But I still find this slightly annoying and not exactly intuitive and straightforward. Actually, it would be excellent if CMake provided something like OH_YEAH_WE_HAVE_DEBUG_BUILD by default, but I can't find any documentation on preprocessor macros provided by CMake.

Owner

mosra commented Apr 10, 2014

Oh, apparently there is COMPILE_DEFINITIONS_<CONFIG> per-target property, which could be used to do exactly what we need, in a cross-platform way:

add_executable(myexe main.cpp)
set_target_properties(myexe PROPERTIES COMPILE_DEFINITIONS_DEBUG "-DOH_YEAH_WE_HAVE_DEBUG_BUILD")

and then, as you suggested, in the configuration file decide about that using preprocessor:

#ifdef OH_YEAH_WE_HAVE_DEBUG_BUILD
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}"
#else
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_RELEASE_DIR}"
#endif

But I still find this slightly annoying and not exactly intuitive and straightforward. Actually, it would be excellent if CMake provided something like OH_YEAH_WE_HAVE_DEBUG_BUILD by default, but I can't find any documentation on preprocessor macros provided by CMake.

@Jagholin

This comment has been minimized.

Show comment
Hide comment
@Jagholin

Jagholin Apr 10, 2014

i would think there are already some things that compiler defines automatically like _DEBUG in VS(i don't know if gcc has them), so i guess one could use it.

Jagholin commented Apr 10, 2014

i would think there are already some things that compiler defines automatically like _DEBUG in VS(i don't know if gcc has them), so i guess one could use it.

@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Apr 10, 2014

Owner

GCC has NDEBUG, which is not defined automatically by the compiler, but rather by the build system. Thus it is possible to have build with debug info and NDEBUG defined, so it is unreliable. Other than that there are apparently no differences in preprocessor symbols when building with or without debug info, the same goes for Clang.

If I won't find anything better I'll probably settle for global preprocessor definition set by Corrade (similarly as it now sets global compiler flags), which could be then used in depending projects instead of setting the property manually every time:

set_property(GLOBAL APPEND COMPILE_DEFINITIONS_DEBUG "-DCORRADE_DEBUG_BUILD")
Owner

mosra commented Apr 10, 2014

GCC has NDEBUG, which is not defined automatically by the compiler, but rather by the build system. Thus it is possible to have build with debug info and NDEBUG defined, so it is unreliable. Other than that there are apparently no differences in preprocessor symbols when building with or without debug info, the same goes for Clang.

If I won't find anything better I'll probably settle for global preprocessor definition set by Corrade (similarly as it now sets global compiler flags), which could be then used in depending projects instead of setting the property manually every time:

set_property(GLOBAL APPEND COMPILE_DEFINITIONS_DEBUG "-DCORRADE_DEBUG_BUILD")
@mosra

This comment has been minimized.

Show comment
Hide comment
@mosra

mosra Jun 5, 2014

Owner

Completed in mosra/corrade@5f49374, e41f4c4 and mosra/magnum-examples@79532ed. Plugin-using examples should now just work in both Debug and Release builds.

Owner

mosra commented Jun 5, 2014

Completed in mosra/corrade@5f49374, e41f4c4 and mosra/magnum-examples@79532ed. Plugin-using examples should now just work in both Debug and Release builds.

@mosra mosra closed this Jun 5, 2014

@mosra mosra added this to the 2014.06 milestone Feb 15, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment