How does one view the actual compiler calls (calls to the clang compiler in my case) that ninja generates when processing a build.ninja file?
Currently, I just get a bunch of summaries like this:
[1/47] Building C object CMakeFiles/proj.dir/home/me/projects/proj/src/native_src.c.o
Whereas I would like to see the actual clang command line call for each source file compile.
The answer is:
ninja -v
In my particular use case I am building a native library for an android project, in which case android studio installs ninja to a directory which isn't on the PATH, i.e.
~/Android/Sdk/cmake/3.6.3155560/bin/ninja -v
Running ninja with this option outputs all the clang compiler calls so you can check they are as you expect
source -> https://ninja-build.org/manual.html#_extra_tools
Related
I have a c++ program, which contains two classes. one of them is using libssh and some of its functions and another one is for calculating cpu usage. there is a link of how I a built and added libssh:libssh's functions couldn't be found on qt my program works fine. now I want to build a .so library out of it to use in other programs. first I made two .o file like this:
gcc -c -fPIC info.cpp -o info.o
gcc -c -fPIC cpuusage.cpp -o cpuusage.o
and I made a .so from them:
gcc -shared -o libsmc.so info.o cpuusage.o
whenever I want to use libsmc.so, I include info.h, but the problem is that libssh functions cannot be found. I think I have to add libssh statically to my project. but I don't know how to!
Ps:I read this explanation :Using a shared library in another shared library , but this is for linking shared libraries that have been used in a program via command line, I don't wanna compile program with command line and want to link libraries constantly.
To build a C/C++ software using external libraries, I would really recommend to use a build system instead of typing commands manually.
The most used build system for C++ is CMake (https://cmake.org/), which is well supported by Qt, but there are many other build systems existing. Another is QMake, which is Qt's build system.
If you are using an IDE, like QtCreator or Microsoft Visual Studio, CMake is integrated as well. There are plenty of tutorials and example to use CMake for a project (e.g. https://mirkokiefer.com/cmake-by-example-f95eb47d45b1), even though the learning curve is not as steep as I would want.
But if you still want to use command line (or to debug the command line generated by CMake): When linking against a library, you need to:
Give the include path to the compiler, i.e. the path where the .h of the external library can be found. With gcc, this is done with -I, e.g. "-I/usr/lib/mylib/include".
Give the library folder and name to the linker, i.e. the path where to find the compiled library, as well as its name. With gcc, this is done with -L for the path and -l for the name. Check the gcc manual for more details about these commands.
And if you want to use CMake, then you can use the functions:
target_include_directories(..)
and
target_link_libraries(..)
I'm building my program with clang and its using an external library. I've been developing for a while with the binaries they provided (/usr/lib/libary.so), but I now want to move over to a more current version.
I downloaded the source code and built it, resulting in an include file and a new library (in my ~/library/build directory).
When compiling my code, I use
clang++ main.cpp -I ~/library/include -L ~/library/build/lib -llibrary
This includes the up to date header, and finds the correct library (I know it finds the correct library, because without the -L flag, I get an error saying 'undefined reference to NewlyIntroducedFunction').
However, when I try to run a.out, I get the error:
./a.out: symbol lookup error: ./a.out: undefined symbol: NewlyIntroducedFunction
Running ldd on ./a.out shows me the line:
library.so => /usr/lib/library.so
So I assume that, although at compile time the correct library is being used, at runtime it isn't. I added ~/library/build to the start of PATH and that didn't work.
What do I do to get the correct version of library.so found?
Your LD_LIBRARY_PATH variable (library search path) is probably not correct
I am getting linker failures under MinGW, however I cannot see why. This is the link command:
g++ -shared -mthreads
-Wl,--out-implib,C:\Users\camm\Syren\libs\libSy_polyMesh.a -o C:\Users\camm\Syren\libs\Sy_polyMesh.dll debug/Sy_polyMesh.o
debug/moc_Sy_polyMesh.o debug/qrc_Sy_polyMesh.o -L"c:\Qt\4.8.4\lib"
-lglu32 -lopengl32 -lgdi32 -luser32 -LC:\Users\camm\Syren/libs -lSyren -lglew32 -lboost_system -lQtSvgd4 -lQtSqld4 -lQtOpenGLd4 -lQtGuid4 -lQtCored4
The undefined reference errors come from the Syren dll (I should state the command was automatically generated by qmake). The -LC:\Users\camm\Syren/libs looks malformed to me because of the mix of forward and backslashes, but if I manually set them to all one way or the other - it does not change the compiler output.
I had earlier problems with 3rd party libraries I needed (GLEW and Boost specifically), but because they were relatively 'constant' I didn't have a problem putting them in my C:\MinGW\lib directory. But that is really not an option for my plugins.
What I find is that the MinGW docs state in a few locations:
...since suitable search paths may always be specified using -L
options.
...but that GCC itself furnishes the effective defaults, by supplying
appropriate -L options.
However, C:\Users\camm\Syren\libs is where Syren.dll resides!
Edit: Here are the LIBS declarations in my .pro file:
LIBS += -L$(SYREN_PATH)/libs \
-lSyren
win32 {
LIBS += -lglew32 \
-lboost_system
}
And $(SYREN_PATH) expands to C:\Users\camm\Syren. Also I can see to the 'missing' symbols in Syren.dll, for example:
C:\Users\camm\Documents\Syren\Sy_polyMesh_debug/../Sy_polyMesh/src/Sy_polyMesh.cpp:341:
undefined reference to `Sy_GLBuffer::unbind()'
Can be seen listed as:
6c500bd6 T _ZN11Sy_GLBuffer6unbindEv
Edit2
After adding a verbose flag to the linker stage I noticed that the linker was iterating through each search path and then through each library naming convention, and using the first one it could open.
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a succeeded
Hypothesizing that the libSyren.a may be broken, I renamed it to force the linker to use the .dll:
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.lib failed
attempt to open C:\Users\camm\Syren/libs/libSyren.dll failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll succeeded
But I still get exactly the same error messages!
If you are linking the right DLL and the linker isn't complaining about a missing file, the dll might be missing exports to allow linking.
The MinGW linker can link directly to a DLL if it properly exports the symbols, although it is still recommended to link to the import library (which should be created in a qmake build) which is named lib*.a or lib*.dll.a. I believe the linker looks for variants with and without the libprefix, but I am unsure and should test this myself.
You can check what symbols a DLL exports by using objdump and/or nm.
If the linker doesn't complain about not being able to load Syren dll, it means that the file is correctly loaded... The symbols are just missing into the Syren dll (not exported ?)... Why it's hard to tell without more information
When you built the Syren lib, did you have any warning about missing prototypes ?
What is used by Syren lib, nothing not portable or requiring a Windows dll ?
Could you give the list of missing symbols ?
Edit : How do you compile the Syren.dll ? Did you use Mingw ? What option did you pass to the compiler / linker ?
I suggest to read these 2 links :
http://www.mingw.org/wiki/sampleDLL
http://www.mingw.org/wiki/CreateImportLibraries
If you are exporting C++ function you must use the same compiler between the program and the DLL. Or you could use a C-style wrapper functions to encapsulate the C++ ABI.
A very good article about this subject : http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
What happens when you replace $(SYREN_PATH) with $${SYREN_PATH}?
Because the former notation $() means the contents of an environment variable at the time Makefile is executed.
See the qmake variable reference.
I usually work on visual c++ 2010 for creating console applications as programming problems. There is this submission which requires me to give the source for the file "Makefile" by some command in unix environment
all:
g++ program.cc -o program
since i don't use unix and have never created a "makefile". I don't know how to make this submission. I have read about a makefile which is supposed to give the directions dependencies etc for compiling the program. I am using the header files iostream string and iterator in the program. i have tried the "all:" command . The bash returns command not found.
Can someone help me with this submission? The code is ready but the only thing stopping for submitting is this "makefile". please include the shell commands as well.
You're missing newline and two tabs (yes, you read right, not spaces) after the all: line, something like this:
all:
g++ helloworld.cc -o helloworld
To invoke make, type make in the directory with the Makefile. Dependencies on system headers are usually not considered, if your code has just one file, you can safely ignore that.
How to change compiler executable name? I want to perform a "fake build" of some products which are using BJam as build system. (For example: the Boost itself) In this "fake build" I want some special command to be called instead of g++. (with all the options and environment used in real build with real gcc).
How to perform this? Are there any command line switches which already allows me to do what I need or maybe I can somehow modify *.jam files to achieve what I need?
The easiest thing might to just switch your path so gcc refers to what you want to run. Otherwise, the correct way to do it bjam is more finicky. I've never gotten it to successfully, easily work, but here's what the docs suggest:
You'll need to add command to the Jamroot of your project to configure the gcc mocking command. The simplest way is just:
using gcc : : my-gcc ;
But most likely you have another using gcc ; line somewhere in your jam rules (or site-config.jam) and you'll get a complaint about trying to reinitialize a toolset. If so, you'll need to give an explicit version to the toolset like so
using gcc : mywrapper : my-gcc ;
And to use this toolset when compiling use the command bjam toolset=gcc-mywrapper.
Good luck.