Troubles at Including (Linking) a static library inside another one - c++

I'll try to explain shortly what I want to do:
A project using a static library which have another one as depandency.
It produce a project called MyProject linking on MyLib1 linking on MyLib2.
Here is the compile order:
MyLib2
MyLib1 (linking to MyLib2)
MyProject (linking to MyLib1)
I'm using Visual Studio 2008 and I have some troubles at defining include.
When linking, I use the property "Additional Include Directory" (on project property C/C++ node).
This seems working between MyProject and MyLib1 but not MyLib1 and MyLib2.
For Exemple: I've a file in MyLib2 called foo.cpp; Using #include "foo.cpp" makes visual studio telling that foo.cpp is unknow (missing file or folder).
To ensure it's NOT a wrong path I gave, I've done many attemps like following: copy-paste the path shown in Command Line (used to compile the library) into win explorer: I well see the source code of my second library. I've remake the project many times and each times I used differents names (forcing me to pay attention to this) and everything seems well defined (but not "including").
The only way I actually find to make it works: using #include "c:\\foo.cpp" as include... Very nice for portability !
Here is a Zip of the Solution to test it yourself and tell me what's wrong: MyProject.rar
Thanks for taking some time to help me !
Lucyberad

First, never include *.cpp files.
Second, use forward declaration of your external functions:
void appellib2(void);
void appellib1(void)
{
appellib2();
}
Third, right-click each project in the Solution Explorer, and select "Project dependencies..." and set-up proper dependencies: MyProject -> MyLib1 -> MyLib2.
At last, in properties for MyProject, set up additional dependencies MyLib1.lib.
Now I can build and run your project without errors.
UPDATE
Never rename *.cpp to *.h just to solve linking problems. If you have a definition in your *.h file you will unable to include it twice or more.
Here is your project YourProject.rar.

I've changed .cpp to .h. I Know I've never to include a CPP file but it was for testing purpose.
I've added prototype of each function but it doesn't works better (It don't include the file mylib2.cpp, the prototype is better but not usefull in this test).
I've set up project dependencies. It still fail.
I've set up additional dependencies MyLib1.lib to MyProject (I think this was the next error I would be able to find, producing a linking a error).
With theses modifications, I still got include error mylib2.h: no such file or directory.
Here is the new archive: MyProject.rar
If you reach to get it working, can you make me an archive of the working solution?
Thanks,
Lucyberad.

Related

CLion not working for any file in another directory

I have a directory structure as follows:
libs/
sdw/
glm-0.9.7.2/
glm/
...
src/
ProjectName.cpp
The sdw directory is full of classes with .cpp and corresponding .h files. Inside any of these files, if I type #include " then it auto-suggests header files within this directory. Syntax highlighting also works for any included classes, as does suggestions for methods etc.,
However, inside ProjectName.cpp, I get no such suggestions for header files, and syntax highlighting plus method suggestions are not present. The only things that work are from the std lib like vector etc.
No files get any highlighting etc., for anything inside the glm directory.
Here is a relevant part of the CMakeLists.txt that was provided to me:
set(GLM_INCLUDE_DIRS libs/glm-0.9.7.2)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS} ${GLM_INCLUDE_DIRS})
include_directories(libs/sdw)
add_executable(ProjectName
libs/sdw/Utils.cpp
libs/sdw/Triangle.cpp
src/ProjectName.cpp)
Inside files like libs/sdw/Utils.cpp I am doing: #include "Triangle.h". This works.
Inside src/ProjectName.cpp I am doing: #include <Utils.h>. This
runs but does not work in the way I want, as described above.
And in everything I am doing #include <glm/glm.hpp> which does not
work in the way I want.
EDIT:
I noticed when opening CLion it promps me to clean the project when loading it. If I click OK then it gives me these errors:
No rule to make target 'all'.
Make execution failed with exit code = 2
No compilation commands found
Deleted .idea and selected CMake project this time (chose Makefile last time)

Add c++ resource to static lib(Visual studio)

I've used #jeff_t's solution as presented here however i encountered several issues.
I have a lib that holds a resource file and set as an external file, file name is
Other Files\myfile.exe
A quick look onto the rc file reveals the following line:
IDR_RES RES "Other Files\\myfile.exe"
Now, i set a DLL project which lays at the same directory level as the LIB and includes both resource.h(Read only symbol directives #include "../LIBProj/resource.h") and LIB.rc(Compile time directives #include "../LibProj/LibProj.rc")
Compiling the LIB goes smoothly, however, when i try to compile the DLL, which links against LIB, results the following error:
../LibProj/LibProj.rc(52): error RC2135: file not found: Other Files\myfile.exe
I do understand that once the linker tries to access additional includes from the DLL projects, it goes out off scope, how to i fix it?
Edit: if i give an absolute path as follows:
IDR_GNRC_RES_AGENT_DATA RES "C:\\Develop\\Code\\LibProb\\Other Files\\myfile.exe"
it works well
After many hours of desperate tries, i realized the solution was quite simple.
I had to use the following path:
IDR_FILE RES "..\LIBProj\Other_Files\\MyFile.exe"
So for both projects that would work. LibProj wont be affected, because we go to the parent directory, and then return back. and for the DllProj we go to parent directory which holds both Lib & Dll projects, and then enter Lib's directory.

link static library in c++ visual studio

can someone please help me to understand the process.
in c++ visual studio 2010
i have a visual studio solution (lets call it mysol)
i have a project built as a static library (let's call it staticprj)
staticprj needs to use a library from outside (lets call it ext.lib)
in the body of the source code of staticprj i include outside library header file with
# include extlib.h and make calls to some of its functions (let call them extfunctions())
i also include the the path to the header files location of the ext.lib.
the staticprj compiles okay without errors
the mysol also has another project which is a dynamic library (dynprj) and which depends on the staticprj.
also in the source files of the dynprj uses functions from outside library.
i have included #include extlib.h in the source code of dynprj.
i have included the path of the header files
i have attached extlib.h directly to the dynprj
i have also added ext.lib to the linker input (along with the path where the ext.lib resides).
i still get a lnk2001 error stating that extfunctions() where not found.
the whole structure (the mysol solution) compiles okay if i do not use ext.lib at all.
my question is how does the linking process works and what can i do to correct this linking error.
(note that without the presence of ext.lib my linking of the staticprj and dynprj is fine. my compilation works okay and my code works. i only get the linking error when i try to link another ext.lib to staticprj and dynprj and use functions from ext.lib)
thanks in advance.
I'm not quite sure it will work, but try putting the .dll inside your "mysol" debug folder. I had a similar problem couple of weeks ago when I had library compiled as .dll. I just placed that .dll within my debug folder and worked lovely.

C++ cross-folder include failing

I've got a project which has two source folders (main and lib). It produces a shared library and an executable. It is currently built as so:
copy all files from both folders into a new temp folder
run lib_makefile
run main_makefile
copy binaries out
delete temp folder
This struck me as being a weird way to do things, so I tried building each in-place by adding -I../main to lib_makefile (and vice-versa). Unfortunately, this doesn't seem to work.
Illustrative example:
foo.cpp (in lib) includes bar.h (in main), which includes baz.h (back in lib).
When I try to compile the shared lib, it correctly locates bar.h in main/, but then bails out with "no such file or directory" claiming it cannot find baz.h, even though baz.h is in the same directory as lib_makefile!
All includes are in the format #include "xxx.h" (i.e no relative paths in the include statements).
Is there a way to get this to work? I feel like I must be missing something obvious..
(nb: I can't modify the #includes because other people still build this the copy-everything-across way)
You should add something like -I../lib (or whatever your library path is) to the makefile for the library as well.
The reason for this is that the pre-processor looks for include-files relative to the directory the current file is in, not from where the original file is in.

How do I resolve LNK1104 error with Boost Filesystem Library in MSCV?

I am having trouble getting my project to link to the Boost (version 1.37.0) Filesystem lib file in Microsoft Visual C++ 2008 Express Edition. The Filesystem library is not a header-only library. I have been following the Getting Started on Windows guide posted on the official boost web page. Here are the steps I have taken:
I used bjam to build the complete set of lib files using:
bjam --build-dir="C:\Program Files\boost\build-boost" --toolset=msvc --build-type=complete
I copied the /libs directory (located in C:\Program Files\boost\build-boost\boost\bin.v2) to C:\Program Files\boost\boost_1_37_0\libs.
In Visual C++, under Project > Properties > Additional Library Directories I added these paths:
C:\Program Files\boost\boost_1_37_0\libs
C:\Program Files\boost\boost_1_37_0\libs\filesystem\build\msvc-9.0express\debug\link-static\threading-multi
I added the second one out of desperation. It is the exact directory where libboost_system-vc90-mt-gd-1_37.lib resides.
In Configuration Properties > C/C++ > General > Additional Include Directories I added the following path:
C:\Program Files\boost\boost_1_37_0
Then, to put the icing on the cake, under Tools > Options VC++ Directories > Library files, I added the same directories mentioned in step 3.
Despite all this, when I build my project I get the following error:
fatal error LNK1104: cannot open file 'libboost_system-vc90-mt-gd-1_37.lib'
Additionally, here is the code that I am attempting to compile as well as a screen shot of the aformentioned directory where the (assumedly correct) lib file resides:
#include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations
#include <iostream> // for std::cout
using boost::filesystem; // for ease of tutorial presentation;
// a namespace alias is preferred practice in real code
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
return 0;
}
Ferruccio's answer contains most of the insight. However, Pukku made me realize my mistake. I am posting my own answer to give a full explanation. As Ferruccio explained, Filesystem relies on two libraries. For me, these are:
libboost_system-vc90-mt-gd-1_37.lib
libboost_filesystem-vc90-mt-gd-1_37.lib
I must not have noticed that when I supplied the directory for libboost_filesystem-vc90-mt-gd-1_37.lib, the error output changed from
fatal error LNK1104: cannot open file 'libboost_filesystem-vc90-mt-gd-1_37.lib'
to
fatal error LNK1104: cannot open file 'libboost_system-vc90-mt-gd-1_37.lib'
Causing me to think that the error was persisting. This lead me to post some rather inaccurate information. Also, after reading that Filesystem requires two libraries, I now see the significance of the keyword stage for the bjam command. Supplying
bjam --build-dir="C:\Program Files\boost\build-boost" --toolset=msvc --build-type=complete stage
Causes bjam to place an additional directory, aptly named stage, in the boost_1_37_0 directory. This folder contains a folder named /lib, which has copies of all of the lib files in one place. This is convenient for Visual C++ because you can supply it with this single directory and it will take care of all of the dependencies.
boost::filesystem is dependent on boost::system, so you need both paths.
Part of the problem is you're using the boost libs out of the build directories instead of the install directory (the boost build process should create both). The install/lib directory has all the libs so you only need to specify one path.
The boost build process builds each library in its own directory. At the end it copies all those .lib files into one common lib directory.
Since you didn't specify an install directory as part of your build command (with --prefix=...), I believe the default is C:\Boost. Check to see if that directory is there and if so use C:\boost\include\ boost-1_37 for your include path and C:\boost\lib for your library path.
Last answer is right.
But you should find boost config file $BOOST\config\user.hpp and
uncomment this directive #define BOOST_ALL_DYN_LINK.
Now it begin use dynamic link with boost and it should works.
I think the real original problem is related to the default boost build process on windows which expects static linking of a library which will have a name beginning libboost_sytem<etc..>. The macro you need is
#define BOOST_SYSTEM_DYN_LINK
which makes ensures that the Boost.System library is dynamically linked. The dynamic library name is boost_system<etc...> as apposed the the static library libboost_sytem<etc...>
The bjam command line should have built all versions of all libraries. Still, when you build with
bjam --build-dir="C:\Program Files\boost\build-boost" --toolset=msvc --build-type=complete stage
(note the stage at the end) all libraries are copied to a common libs/ folder, so that MSVC's autolinking feature works when you only add this libs/ folder to your library path.
I do not know if bjam without stage still copies all those files to a single folder. If not, execute such a stage build to do this. If they are, well, sorry, configuration seems correct, maybe a minor typing error somewhere?
The error you have posted complains about file libboost_system-vc90-mt-gd-1_37.lib, but in the directory you have only libboost_filesystem-vc90-mt-gd-1_37.lib, right?
Look for libboost_system-vc90-mt-gd-1_37.lib. If you find it, add the corresponding directory to the library search path. If you don't find it, see if you have boost_system-vc90-mt-gd-1_37.lib instead (like I do), and try copying that to the desired filename.
I had this same problem, what you need to do is add the "lib" directory under the top level boost folder to the library path in Visual C++.
This most definitely solved the issue for me.