2
votes

Depending on the build type (debug, release) of my main executable, I want to link against the matching builds of my DLLs. What is the correct way to accomplish this using the C++Builder IDE?

Details: I am using Embarcadero C++Builder XE8 (trial, BCC64). My software consists of one executable and multiple libraries (.dll, Dynamic-link Library) loaded during program startup (not at runtime). Each library and executable has its own project and all projects are within the same project group.

To use the compiled libraries in the consuming projects, I have added the import files of the compiled DLLs (.a for BCC64) to the consuming project.

Excerpt from SerialPort.cbproj:

<LibFiles Include="..\..\Win64\Debug\Logger.a" Condition="'$(Platform)'=='Win64'">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>

Unfortunately, the output path for .dll/.a files depends on the variables $(Platform) and $(Config) and therefore the path to those files differs between debug and release builds. The IDE does not(!?) allow me to specify different DLL files to be used for debug and release builds.

I'd rather not resort to ugly hacks like putting the generated binaries for debug and release mode in the same folder just to have a single path to the import files for both builds. The following workaround seems to work, but gets overwritten by C++Builder when saving the project:

<LibFiles Include="..\..\Win64\Debug\Logger.a" Condition="('$(Platform)'=='Win64') And ('$(Config)'=='Debug')">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>
<LibFiles Include="..\..\Win64\Release\Logger.a" Condition="('$(Platform)'=='Win64') And ('$(Config)'=='Release')">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>

Is there a sane way to solve this problem?

2
I could be wrong, but I understood that when you compile an .exe in debug mode it looks at the debug path, and when you compile in release mode it looks at the release path. Is it not doing that for you? - caps
And an EXE project also has $(Platform) and $(Config) variables as well. So if the DLLs, their import LIBs, and the EXE are all compiled into the same folder based on build configs, then everything should be working fine provided the DLLs/LIBs are using the same filename for each config. - Remy Lebeau
I have (!?) to specify the .a file to be used in a consuming project. Therefore, it does not help when the dll and exe end up in the same directory after building. - rettichschnidi
You could use #pragma link macros instead of adding the libraries to the project directly. That way you can control this with a simple #define which you could specify on the project configuration. - Rodrigo Gómez
@RodrigoGómez: Thanks, this is a quite usable workaround. I'll go with that until a better solution gets proposed. - rettichschnidi

2 Answers

2
votes

As mentioned on the comments, one possible solution is:

Instead of adding the lib/a files to the project, you can use the #pragma link directive in one of your source files to link them. And you can surround it with #ifdef directives to control which files to link in which conditions, that you can define on the project options.

Something like:

#ifdef DEBUG
  #pragma link "mydebulib.a"
#else
  #pragma link "myreleaselib.a"
#endif
0
votes

Each library and executable has its own project and all projects are within the same project group

I'd go with:

#pragma comment(lib, "Logger")

In this way if you change something in the library and then try to build the executable, C++Builder automatically rebuilds Logger.a (it doesn't happen with pragma link).

Also consider that the files named in #pragma link / #pragma comment statements should not contain a file extension. The compiler will append the appropriate one: .lib when targeting Win32 / .a then targeting Win64.

As noted the library path itself can be specified in the project options, where $(PLATFORM) and $(CONFIG) can be used.


NOTE C++Builder 10.3 Rio Release 2 requires a hotfix or, in some situations, modifying a file in the IDE followed by making or compiling the project would not build the modified file into the resulting binary (see RSP-25525 or the Embarcadero Blog for further details).