I am building a library project and a test project to test this library on. I want the user (A.K.A. the test project) to be able to define some things for the library, but the #define is not recognized in my library and just throws an error.
**I am building the library project as static library, the build order is that the library builds first and then the test project since the project is dependent on the library.
In the test project I want the user to be able to define like this (before the include):
#define PUT_DEFINE_HERE
In the library I just check with:
#ifdef PUT_DEFINE_HERE
//Do some stuff
#endif
As stated before the library does not see the #define defined by the user. I tried some stuff with the build order but no luck so far, any ideas?
If you want the library to "accept" a user #define, the check on the presence of PUT_DEFINE_HERE
#ifdef PUT_DEFINE_HERE
//Do some stuff
#endif
must be done at the header lever, and only there
Secondly, the user project which includes the library header must #define PUT_DEFINE_HERE before including the library header.
Alternatively, if such a setting is incompatible with the library design, then the #define must be added at compile time, e.g.:
gcc -DPUT_DEFINE_HERE ...
In this case, be sure to compile every source with -DPUT_DEFINE_HERE, when relevant.
I've downloaded the latest copy from Latest Open EXR repo and compiled most everything without any problems. However, when I get to PyILMBase it fails.
There are two distinct issues with my attempts:
Error C2491 'PyImath::FixedArray::name': definition of dllimport function not allowed PyImath (...)\src\pyilmbase-2.2.1\PyImath\PyImath.cpp 41
and an import to unistd.h that kind of gets addressed Here
my question being, has anybody successfully compiled this for windows? It seems odd that I can't find any specific info about that compiling error. Am I missing something in the way that C++ works?
This project makes extensive use of whatever it is that causes the error C2491, so going in and changing it would be a little complicated
IlmBase is compiled as a shared library. A shared library must provide their function declarations in order your program can find them.
It's perform by declaring them as dllimport or dllexport depending on the situation.
__declspec(dllimport): imports the implementation from a DLL so your application can use it.
__declspec(dllexport): tells the linker that you want this object to be made available for other DLL's to import. It is used when creating a DLL that others can link to.
These keywords are generally handled by a single macro. In your case PYIMATH_EXPORT.
These lines are from PyImathTask.h
#if defined(PYIMATH_EXPORTS) // create library
#define PYIMATH_EXPORT __declspec(dllexport)
#else // use library
#define PYIMATH_EXPORT __declspec(dllimport)
#endif
So, because you want to make these functions available from your application, you must add PYIMATH_EXPORTS as a preprocessor definition.
Actually, PyIMath's properties mispells it - they've write it as PyImath_EXPORTS - ...
To fix that, in vs2015, go to the PyImath's properties > Configuration Properties > C/C++ > Preprocessor > Replace PyImath_EXPORTS by PYIMATH_EXPORTS.
It's probably the same thing for PyIex...
I have 4 files, linuxasm.h linuxasm.cpp windowsasm.h and windowsasm.cpp
in the main.cpp i have
#ifdef __linux
#include "linuxasm.h"
#elif _WIN64
#include "winasm.h"
#endif
the function names in the .cpps are identical
is there a way to prevent GCC from complaining about multiple definitions of functions?
Or should I go about it another way?
You should do it some other way. I would use your build system to omit the appropriate .cpp file from the build based on architecture (if I understand your situation correctly).
Basically, for one target, say Win64, the windowsasm.cpp is a dependency and is compiled; similarly for Linux. Look up how your system is managing dependencies for the build and give it a try.
I have created several C++ libraries that currently are header-only. Both the interface and the implementation of my classes are written in the same .hpp file.
I've recently started thinking that this kind of design is not very good:
If the user wants to compile the library and link it dynamically, he/she can't.
Changing a single line of code requires full recompilation of existing projects that depend on the library.
I really enjoy the aspects of header-only libraries though: all functions get potentially inlined and they're very very easy to include in your projects - no need to compile/link anything, just a simple #include directive.
Is it possible to get the best of both worlds? I mean - allowing the user to choose how he/she wants to use the library. It would also speed up development, as I'd work on the library in "dynamically-linking mode" to avoid absurd compilation times, and release my finished products in "header-only mode" to maximize performance.
The first logical step is dividing interface and implementation in .hpp and .inl files.
I'm not sure how to go forward, though. I've seen many libraries prepend LIBRARY_API macros to their function/class declarations - maybe something similar would be needed to allow the user to choose?
All of my library functions are prefixed with the inline keyword, to avoid "multiple definition of..." errors. I assume the keyword would be replaced by a LIBRARY_INLINE macro in the .inl files? The macro would resolve to inline for "header-only mode", and to nothing for the "dynamically-linking mode".
Preliminary note: I am assuming a Windows environment, but this should be easily transferable to other environments.
Your library has to be prepared for four situations:
Used as header-only library
Used as static library
Used as dynamic library (functions are imported)
Built as dynamic library (functions are exported)
So let's make up four preprocessor defines for those cases: INLINE_LIBRARY, STATIC_LIBRARY, IMPORT_LIBRARY, and EXPORT_LIBRARY (it is just an example; you may want to use some sophisticated naming scheme).
The user has to define one of them, depending on what he/she wants.
Then you can write your headers like this:
// foo.hpp
#if defined(INLINE_LIBRARY)
#define LIBRARY_API inline
#elif defined(STATIC_LIBRARY)
#define LIBRARY_API
#elif defined(EXPORT_LIBRARY)
#define LIBRARY_API __declspec(dllexport)
#elif defined(IMPORT_LIBRARY)
#define LIBRARY_API __declspec(dllimport)
#endif
LIBRARY_API void foo();
#ifdef INLINE_LIBRARY
#include "foo.cpp"
#endif
Your implementation file looks just like usual:
// foo.cpp
#include "foo.hpp"
#include <iostream>
void foo()
{
std::cout << "foo";
}
If INLINE_LIBRARY is defined, the functions are declared inline and the implementation gets included like a .inl file.
If STATIC_LIBRARY is defined, the functions are declared without any specifier, and the user has to include the .cpp file into his/her build process.
If IMPORT_LIBRARY is defined, the functions are imported, and there isn't a need for any implementation.
If EXPORT_LIBRARY is defined, the functions are exported and the user has to compile those .cpp files.
Switching between static / import / export is a really common thing, but I'm not sure if adding header-only to the equation is a good thing. Normally, there are good reasons for defining something inline or not to do so.
Personally, I like to put everything into .cpp files unless it really has to be inlined (like templates) or it makes sense performance-wise (very small functions, usually one-liners). This reduces both compile time and - way more important - dependencies.
But if I choose to define something inline, I always put it in separate .inl files, just to keep the header files clean and easy to understand.
It is operating system and compiler specific. On Linux with a very recent GCC compiler (version 4.9) you might produce a static library using interprocedural linktime optimization.
This means that you build your library with g++ -O2 -flto both at compile and at library link time, and that you use your library with g++ -O2 -flto both at compile and link time of the invoking program.
This is to complement #Horstling's answer.
You can either create a static or a dynamic library. When you create statically-linked libraries, compiled code for all functions/objects will be saved to a file (with .lib extension in Windows). At main project (the project using the library) 's link time, these codes will be linked into your final executable together with the main project codes. So the final executable wouldn't have any runtime dependency.
Dynamically linked libraries will be merged into the main project at run time (and not link time). When you compile the library you get a .dll file (which contains actual compiled code) and a .lib file (which contains enough data for the compiler/runtime to find functions/objects in the .dll file). At link time, the executable will be configured to load the .dll and use compiled code from that .dll as needed. You will need to distribute the .dll file with your executable to be able to run it.
There is no need to choose between static or dynamic linking (or header-only) when designing your library, you create multiple project/makefiles, one to create a static .lib, another to create a .lib/.dll pair, and distribute both versions, for the user to choose between. (You'll need to use preprocessor macros like the ones #Horstling suggested).
You cannot put any templates in a pre-compiled library, unless you use a technique called Explicit Instantiation, which limits template parameters.
Also note that modern compiler/linkers usually do not respect the inline modifier. They may inline a function even if it's not designated as inline, or may dynamically call another that has inline modifier, as they see fit. (Regardless, I'll advise explicitly putting inline where applicable for maximum compatibility). So, there won't be any runtime performance penalty if you use a statically linked library instead of a header-only library (and enable compiler/linker optimizations, of course). As others have suggested, for really small functions that are sure to benefit from being called inline, it is best practice to put them in header files, so dynamically linked libraries will also not suffer any significant performance loss. (In any case, inlining functions will only affect performance for functions that are being called very often, inside loops that are going to be called thousands/millions of times).
Instead of putting inline functions in header files (with an #include "foo.cpp" in your header), you can change makefile/project settings and add foo.cpp to the list of source files to be compiled. This way, if you change any function implementation there will be no need to re-compile the whole project and only foo.cpp will be re-compiled. As I mentioned earlier, your small functions will still be inlined by the optimizing compiler, and you don't need to worry about that.
If you use/design a pre-compiled library, you should consider the case where the library is compiled with a different version of compiler to the main project. Each different compiler version (even different configurations, like Debug or Release) uses a different C runtime (things like memcpy, printf, fopen, ...) and C++ standard library runtime (things like std::vector<>, std::string, ...). These different library implementations may complicate linking, or even create runtime errors.
As a general rule, always avoid sharing compiler runtime objects (data structures that are not defined by standards, like FILE*) across libraries, because incompatible data structures will lead to runtime errors.
When linking your project, C/C++ runtime functions must be linked into your library .lib or .lib/.dll, or your executable .exe. C/C++ runtime itself can be linked as static or dynamic library (you can set this in makefile/project settings).
You will find that dynamically linking to C/C++ runtime in both the library and the main project (even when you compile the library itself as a static library) avoids most linking problems (with duplicate function implementations in multiple runtime versions). Of course you would need to distribute runtime DLLs for all used versions with your executable and library.
There are scenarios that statically linking to C/C++ runtime is needed, and the best approach in these cases would be to compile the library with the same compiler setting as the main project to avoid linking problems.
Rationale
Put as little as necessary in header files and as much as possible in library modules, because of the very reasons that you mentioned: compile-time dependency and long compilation time. The only good reasons for header-only modules are:
generic templates for user-defined template parameter;
very short convenience functions when inlining gives significant
performance.
In case 1, it is often possible to hide some functionality that does not depend on the user-defined type in a .cpp file.
Conclusion
If you stick to this rationale, then there is no choice: templated functionality that must allow user-defined types cannot be pre-compiled, but requires a header-only implementation. Other functionality should be hidden from the user in a library to avoid exposing them to the implementation details.
Rather than a dynamic library, you could have a precompiled static library and thin header file. In an interactive quick build, you get the benefit of not having to recompile the world if implementation details changes. But a fully optimized release build can do global optimization and still figure out it can inline functions. Basically, with "link-time code generation" the toolset does the trick you were thinking about.
I'm familiar with Microsoft's compiler, which I know for sure does this as of Visual Studio 2010 (if not earlier).
Templated code will necessarily be header-only: for instantiating this code, the type parameters must be known at compilation time. There is no way to embed template code in shared libraries. Only .NET and Java support JIT instantiation from byte-code.
Re: non-template code, for short one-liners I suggest keeping it header-only. Inline functions give the compiler a lot more opportunities to optimize the final code.
To avoid "insane compilation time", Microsoft Visual C++ has a "precompiled headers" feature. I do not think GCC has a similar feature.
Long functions should not be inlined in any case.
I had one project which had header-only bits, compiled library bits and some bits I could not decide where belonged. I ended up having .inc files, conditionally included in either .hpp or .cxx depending on #ifdef. Truth to be told, the project was always compiled in "max inline" mode, so after a while I got rid of the .inc files and simply moved the contents to .hpp files.
Is it possible to get the best of both worlds?
In terms; limitations arise because tools aren't smart enough. This answer gives the current best effort that is still portable enough to be used effectively.
I've recently started thinking that this kind of design is not very good.
It ought to be. Header-only libraries are ideal because they simplify deployment: makes the reusing mechanism of the language similar to almost all others', which is just the sane thing to do. But this is C++. Current C++ tools still rely on half-a-century-old linking models that remove important degrees of flexibility, such as choosing which entry points to import or export on an individual level without being forced to change the library's original source code. Also, C++ lacks a proper module system and still relies on glorified copy-paste operations to work (although this is just a side factor to the problem in question).
In fact, MSVC is a little better in this regard. It is the only major implementation trying to achieve some degree of modularity in C++ (by attempting e.g. C++ modules). And it is the only compiler that actually allows e.g. the following:
//// Module.c++
#pragma once
inline void Func() { /* ... */ }
//// Program1.c++
#include <Module.c++>
// Inlines or "vague" links Func(), whatever is better.
int main() { Func(); }
//// Program2.c++
// This forces Func() to be imported.
// The declaration must come *BEFORE* the definition.
__declspec(dllimport) __declspec(noinline) void Func();
#include <Module.c++>
int main() { Func(); }
//// Program3.c++
// This forces Func() to be exported.
__declspec(dllexport) __declspec(noinline) void Func();
#include <Module.c++>
Note that this can be used to selectively import and export individual symbols from the library, although still cumbersomely.
GCC also accepts this (but the order of the declarations must be changed) and Clang does not have any way to achieve the same effect without changing the library's source.
In a *.cpp file, trying to use a third party lib:
#define DLL_IMPORT
#include <thirdParty.h>
// Third party header has code like:
// #ifdef DLL_IMPORT
// #define DLL_DECL __declspec(dllimport)
// fatal error C1001: An internal error has occurred in the compiler.
Alternative:
#define NO_DLL
#include <thirdParty.h>
// Third party header has code like:
// #elif defined(NO_DLL)
// #define DLL_DECL
// Compiles fine, but linker errors as can't find DLL functions
I can reproduce results by remove macros and #define all together and manually editing the third party files to have __declspec(dllimport) or not - so the preprocessor stuff above is just to show what's going on, it's not copy-paste.
Has anyone come across anything similar, or can hint at the cause? (which is created using CMake). Above is actual example of 2 line *.cpp that crashes so it's narrowed down to something in the #include.
The following also work fine:
Compile the examples provided by the third party (they provide a *.sln) that use dllimport/export so it doesn't appear to be the fault of the library
Compile the third party lib as part of the production project (so dllexport works fine)
I've trawled the project settings pages of the two projects to try and spot differences, but have come up blank. Of course, it's possible I'm missing something as those settings pages are not the easiest to navigate. I'll get access to VS2008 in a day or so, so can compare with that. The third party library is MySql++.
A compiler crash is definitely a bug in the compiler, so you're best off submitting an error report to the Microsoft Visual C++ team.
As for the error
#define DLL_DECL __declspec(dllimport)
is the wrong way to go about things. There should be some project setting you need to set, a pre-processing directive you can define instead if DLL_DECL, or simply including a different file.
Turns out it was because precompiled headers was turned on for the project trying to use the DLL.