CMake target to just compile a source file - c++

I am writing a header-only library using C++17. I would like to include it in a "dummy" source file:
#include "my/library.h"
// EOF
The purpose is to ensure the library properly includes all of its dependencies. I also want to run static analyzers on it and compile it with as many compiler checks enabled as is practical.
To create a normal executable target I need to add the main() function, otherwise the linking stage will fail.
I guess I can also create a static library target, which should work correctly, although it will create an artifact I do not need.
Is there any other alternative?

CMake can create a simple Object library, which will only be a .o or .obj file:
The OBJECT library type defines a non-archival collection of object files resulting from compiling the given source files.
To do this, use the OBJECT keyword with the add_library() command:
add_library(MyObj OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/library.cpp)
target_include_directories(MyObj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
You can later reference the object file(s) to be compiled into other libraries or executables:
add_library(MyLibrary STATIC
$<TARGET_OBJECTS:MyObj>
MyOtherSource.cpp
HelpersFunctions.cpp
)

Most compilers allow you to override the default extension for input types. If you just pass my/library.h as the input file to the compiler, it can compile that into a library.o or library.obj.
Note that short of compiling an executable, you can't be sure that your library.h is complete. In particular, C++ requires that non-inline static const class members are defined exactly once per program if they're odr-used. So if you forget inline in your library.h, you might not notice this in your simple test. And even if you'd add an empty main(), that still wouldn't odr-use those members.

Related

How to compile a static library with Codelite 11.0.0?

I would like to compile a static library out of all the functions I have written for a C++ project. I am using CodeLite 11.0.0 on Ubuntu 16.04, configured to use GCC as compiler.
I have followed the instructions in CodeLite's tutorial, according to which this should be possible, and changed the project type from Executable to Static Library.
After running the project (CTRL+F5 command), I expected to find a .a file in the /Debug folder, either along with, or in place of the executable file. All I could find, though, was the executable and a number of .o and .o.d files. The same I was finding when the project was set to Executable.
I tried to close and reopen CodeLite, but it did not help. I can't find any official/unofficial example of how to build a static library with CodeLite.
Does anyone know how to set-up CodeLite to produce a .a static library file?
As you've probably discovered, CodeLite allows you to change the type of a
project in the drop-down menu from Settings -> General -> Project type.
Doing so, however, does not change the name of the project target. So, if
you started off your project as an executable myprog - from which, say, the
Debug build generated ./Debug/myprog under the project folder - then
you change the project type to static library and rebuild it, the Debug
build will still generate ./Debug/myprog, but that file will now in fact
be a static library, lacking the customary lib-prefix and .a extension.
To give the output file a conventional static library name -
libmyprog.a - you need to go back into Settings -> General and
change Output File from:
$(IntermediateDirectory)/$(ProjectName)
to:
$(IntermediateDirectory)/lib$(ProjectName).a
Then rebuild the project and it will output a target that is a static
library and looks like one.
Of course, you must make the same changes to the project settings in both
the Debug and Release configurations if you want them both to produce
targets with the same file type and file name.
However...
If this way of converting a program project to a static library project does not
seem very slick, that could be because it is a conversion of very little use.
The static library produced after the conversion will contain exactly the same object
files that the program was built from, including the object file that defines
the main function of the original program. Let's suppose that object file
is main.o, and that it defines 0 or more other functions that the linker can see.
Any other program, newprog, that is linked with the static library must provide
its own main function in a different object file, so in any such linkage one of
two things must happen:-
The linkage of newprog does not need any function defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is not linked and might as well not exist.
The linkage of newprog does need some function, foo, defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is linked; then as well as the definition of foo, the
program links duplicate definitions of main - its own definition plus the
one in libmyprog.a(main.o). Duplicate definitions are an error, so the linkage fails.
Putting a definition of some program's main function into a member of a static
library is pointless, because if that member is ever needed in the linkage of another
program then its linkage will fail.
So converting your program project to a static library project calls for some
refactoring prior to the conversion:-
If any function that you want in the static library is defined in the same source
file as main, then you need to take it out of that source file and define it
is a different one.
After that, remove the source file that defines main from the project.
Lastly, convert and rebuild the project.
You have to do that refactoring to extract from your original program source code
a bunch of source files that are suitable for building into a static library.
Assuming you've done that, the straightforward way to create a static library with
CodeLite is to create a project for that purpose and in the New Project Wizard
choose Library -> Static Library as the project type instead of some kind
of executable.
Then just add either new or existing source files to the static library project
until it contains definitions of all the functions you want the library to
provide. Build, test, debug, edit... until done.

compilation flag doesn't apply static linked library

I'm working on Xcode project where I have a static library that is linked to another library which i compile with flag -DMODULE in "other C Flags (see images) .
However, during execution when I reach one of the static library functions, the MODULE doesn't defined anymore, any idea why ?
Static library is linked prior to runtime, and composed from a bunch of .o files, so i would assume those are having the same treatment as any other .o file in the parent library that the flag applies to. Am i missing something ?
Compiler defines are applied during the conversion from source to object (.o). A static library is just a bunch of .o files glued together. If you already have a static library, you can't apply defines to it anymore. If you need to change the defines, you'll need to recompile the source rather than using a static library.
Remember that compiler defines are applied by the pre-processor. They replace part of the source code text with some other text. They're applied before the compiler even sees the code (let alone the linker).

How Iostream file is located in computer by c++ code during execution

i want to know that in a c++ code during execution how iostream file is founded. we write #include in c++ program and i know about #include which is a preprocessor directive
to load files and is a file name but i don't know that how that file is located.
i have some questions in my mind...
Is Standard library present in compiler which we are using?
Is that file is present in standard library or in our computer?
Can we give directory path to locate the file through c++ code if yes then how?
You seem to be confused about the compilation and execution model of C++. C++ is generally not interpreted (though it could) but instead a native binary is produced during the compilation phase, which is then executed... So let's take a detour.
In order to go from a handful of text files to a program being executed, there are several steps:
compilation
link
load
execution proper
I will only describe what traditional compilers do (such as gcc or clang), potential variations will be indicated later on.
Compiling
During compilation, each source file (generally .cpp or .cxx though the compiler could care less) is processed to produced an object file (generally .o on Linux):
The source file is preprocessed: this means resolving the #include (copy/pasting the included file in the current file), navigating the #if and #else to remove unneeded sources and expanding macros.
The preprocessed file is fed to the compiler which will produce native code for each function, static or global variable, etc... the format depends on the target system in general
The compiler outputs the object file (it's a binary format, in general)
Linking
In this phase, multiple object files are assembled together into a library or an executable. In the case of a static library or a statically-linked executable, the libraries it depend on are also assembled in the produced file.
Traditionally, the linker job is relatively simple: it just concatenates all object files, which already contain the binary format the target machine can execute. However it often actually does more: in C and C++ inline functions are duplicated across object files, so the linker need to keep only one of the definitions, for example.
At this point, the program is "compiled", and we live the realm of the compiler.
Loading
When you ask to execute a program, the OS will load its code into memory (thanks to a loader) and execute it.
In the case of a statically linked executable, this is easy: it's just a single big blob of code that need be loaded. In the case of a dynamically linked executable, it implies finding the dependencies and "resolving the symbols", I'll describe this below:
First of all, your dynamically linked executable and libraries have a section describing which other libraries they depend on. They only have the name of the library, not its exact location, so the loader will search among a list of paths (LD_LIBRARY_PATH for example on Linux) for the libraries and actually load them.
When loading a library, the loader will perform replacements. Your executable had placeholders saying "Here should be the address of the printf function", and the loader will replace that placeholder with the actual address.
Once everything is loaded properly, all symbols should be resolved. If some symbols are missing, ie the code for them is not found in either the present library or any of its dependencies, then you generally get an error (either immediately, or only when the symbol is actually needed if you use lazy loading).
Executing
The code (assembler instruction in binary format) is now executed. In C++, this starts with building the global and static objects (at file scope, not function-static), and then goes on to calling your main function.
Caveats: this is a simplified view, nowadays Link-Time Optimizations mean that the linker will do more and more, the loader could actually perform optimizations too and as mentioned, using lazy loading, the loader might be invoked after the execution started... still, you've got to start somewhere, don't you ?
So, what does it mean about your question ?
The #include <iostream> in your source code is a pre-processor directive. It is thus fully resolved early in the compilation phase, and only depends on finding the appropriate header (no library code is actually needed yet). Note: a compiler would be allowed not to have a header file sitting around, and just magically inject the necessary code as if the header file existed, because this is a Standard Library header (thus special). For regular headers (yours) the pre-processor is invoked.
Then, at link-time:
if you use static linking, the linker will search for the Standard Library and include it in the executable it produces
if you use dynamic linking, the linker will note that it depends on the Standard Library file (libc++.so for example) and that the produced code is missing an implementation of printf (for example)
Then, at load time:
if you used dynamic linking, the loader will search for the Standard Library and load its code
Then, at execution time, the code (yours and its dependencies) is finally executed.
Several Standard Library implementations exist, off the top of my head:
MSVC ships with a modified version of Dirkumware
gcc ships with libstdc++ (which depends on libc)
clang ships with libc++ (which depends on libc), but may use libstdc++ instead (with compiler flags)
And of course, you could provide others... probably... though setting it up might not be easy.
Which is ultimately used depends on the compiler options you use. By default the most common compiler ship with their own implementation and use it without any intervention on your part.
And finally yes, you can indeed specify paths in a #include directive. For example, using boost:
#include <boost/optional.hpp>
#include <boost/algorithm/string/trim.hpp>
you can even use relative paths:
#include <../myotherproject/x.hpp>
though this is considered poor form by some (since it breaks as soon as your reorganize your files).
What matters is that the pre-processor will look through a list of directories, and for each directory append / and the path you specified. If this creates the path of an existing file, it picks it, otherwise it continues to the next directory... until it runs out (and complain).
The <iostream> file is just not needed during execution. But that's just the header. You do need the standard library, but that's generally named differently if not included outright into your executable.
The C++ Standard Library doesn't ship with your OS, although on many Linux systems the line between OS and common libraries such as the C++ Standard Library is a bit thin.
How you locate that library is very much OS dependent.
There can be 2 ways to load a header file (like iostream.h) in C++
if you write the code as:
# include <iostream>
It will look up the header file in include directory of your C++ compiler and will load it
Other way you can give the full path of the header file as:
# include "path_of_file.h"
And loading up the file is OS dependent as answered by MSalters
You definitely required the standard library header files so that pre-processor directive can locate them.
Yes those files are present in the library and on include copied to our code.
if we had defined the our own header file then we have to give path of that file. In that way we can include also *.c or *.cpp along with the header files in which we had defined various methods and those had to include at pre-processing time.

how to use a class of a different directory

I want to use an object of the class C, in the class D.
The tree of directories of the program is similar to:
directory1/directory2/main.cc
directory1/directory2/classC.cc
directory1/directory2/classC.h
directory1/directory3/classD.cc
directory1/directory3/classD.h
I've included the header in classD.h with the absolute path of the classC, but if I try to run I get this error:
Undefined reference to nm1::ClassC::ClassC()
In classD I call the object in this way: nm1::ClassC * obj = new ClassC();
I added to the wscript the correct headers with correct paths.
ClassC make part of the nm1 namespace, ClassD make part of the nm1::nm2 namespaces.
How could I do?
The problem here is that each .cc file is compiled separately. At compile time, they're told by headers there is a function/class/constructor called x but not the implementation details of that function/class, because that is in the .cc file which has been compiled separately.
At link time, you need to either dynamically, or statically link another library, or combine object files into the same executable. This is done by the linker. The error you are receiving there is because at link time, the class ClassC you have promised is there, by including the header, has not been found in any of the libraries or objects that you have linked against.
Your headers are fine. I can't really tell you how to link properly because I don't know what compiler/linker you're using. But look up how to add linker paths to your link command. Also make sure you're compiling every file, and that each compile is producing some kind of object output, then check what is consuming those.
try to use
#include<file path>
or
#include"file path"
where file path is full file path with C:.... if you are using windows

LNK4221 and LNK4006 Warnings

I am making a static library of my own. I have taken my code which works and now put it into a static library for another program to use. In my library I am using another static library which I don't want the people who will be using my API to know. Since, I want to hide that information from them I can't tell them to install the other static library.
Anyway, I used the command line Lib.exe to extract and create a smaller lib file of just the obj's I used. However, I get a bunch of LNK4006 :second definition ignored linker warnings for each obj I use followed by LNK4221 no public symbols found;archive member will be inaccessible.
I am doing this work in vs2008 and I am not sure what I am doing wrong.
I am using the #pragma comment line in my .cpp file
I have also modified the librarian to add my smaller .lib along with its location.
my code simply makes calls to a couple functions which it should be able to get from those Obj file in the smaller lib.
All my functions are implemented in .cpp file and my header just have the includes of the third party header files and come standard c++ header files. nothing fancy. I have actually no function definitions in there atm. I was going to put the API definition in there and implement that in the .cpp for this static lib that i was going to make. However, I just wanted to build my code before I added more to it.
I did read http://support.microsoft.com/default.aspx?scid=kb;EN-US;815773 but it did not provide a solution.
Even if you extract all objects from the other library and put them in your own library, your users will still be able to see what's in your library and thus see all the object names. In many cases the names of the objects will reveal what's actually the other library you are using.
Instead of distributing your library as a static library, consider distributing it as a DLL. In the DLL you can easily hide all the underlying things and only make public what you want to make public.