What's the usage of Golang static library file? - go

I see go install <main package> will compile the dependency packages into static library files and install them into the pkg directory, but the executable doesn't need the library files when running. And I also discover that source file is necessary when compiling.
So, is there any special usage of the static files?

The compiled packages can be reused if you compile something else. This saves time on subsequent compiles. When you recompile you only need to compile the package and the things that depend on it, not its dependencies.
They also contain data used by gocode for autcompleting.

Related

Run make install command in cmake from another cmake file

We have multiple libraries in different folder, The main application needs to build those libraries in other folders and install them to output folder and then the main application needs to link to libraries to build executable.
I am able to build the libraries present in other folders using add_subdirectory() in a loop, but I am not able to install them to output folder by main cmake file. Could anyone help me out on this.
The main application needs to build those libraries in other folders and install them to output folder and then the main application needs to link to libraries to build executable.
It is not necessary in CMake to install libraries in order to link to them. You can build the libraries and have your main executable link to them without installing the libraries. When you need to install your application as a whole, you can install libraries along with the executable if needed i.e. if the libraries are shared ones and not static ones.
One example of how you can organize things: assume you have the following structure in your project:
CMakeLists.txt # root of project
|
|--lib
| |--CMakeLists.txt # library subproject
|
|--app
|--CMakeLists.txt # app subproject
Then your root CMakeLists.txt can look like this:
project(MyProject)
add_subdirectory(lib)
add_subdirectory(app)
The lib subproject's CMakeLists.txt can look like this:
project(MyLib)
set(SOURCES <...>) # specify library's sources
add_library(${PROJECT_NAME} ${SOURCES})
set(MyLib ${PROJECT_NAME} CACHE INTERNAL "")
The last line in the snippet above is aimed to make MyLib variable available everywhere within the project. I found this trick here and used it successfully in my projects. Maybe there are better options here, if anyone knows them, feel free to suggest.
The app's CMakeLists.txt can then look like this:
project(MyApp)
set(SOURCES <...>) # specify app's sources
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${MyLib})
I haven't covered the installation here but it's actually straightforward: if your libraries are static ones, you only need to install the executable using install TARGETS. If your libraries are shared ones, you need to install them along with the executable.

How to extract kernel headers for compiling kernel module later

I compiled various Linux kernel from git repositories. There are times when I copied the kernel to other system and need the kernel header to compile external module.
I tried to run "make headers_install" but it only generated a include/ folder. When I tried to point external module to that folder, it complains it cannot find Makefile.
What is the proper way to package kernel-header for deployment?
Thanks.
Create kernel packages instead, that's "make deb-pkg" for dpkg based distros and "make rpm-pkg" for RPM based ones. These create multiple packages, one of those is a package usable for external modules building. That should be linux-headers-* for the Debian packages and a "devel" package for he RPM versions.
In some ways this is just an expansion of the previous answer. If you look at the file scripts/package/builddeb in the kernel sources you will find script code which selects the files needed for building external modules from a kernel build and puts them into /usr/src/linux-headers-$version. I can find that script code in my local kernel version by searching for the string "# Build kernel header package" in the builddeb file. If you want to do things by hand you could execute that script code manually.

Does Boost BCP also copy the required LIB files?

This may be a no-brainer for longtime boost users, but I’m just getting into boost.
I built the full boost distribution and BCP to extract just the parts I need to put in my VisualStudio C++ project.
What I found is when I call bcp, it copies the source tree to the destination. It doesn’t copy the required compiled lib files though (for those modules that need it).
So when I build my project and include
#include "boost/program_options.hpp"
for example, I get a linker error:
*Error 1 error LNK1104: cannot open file 'libboost_program_options-vc100-mt-sgd-1_54.lib'*
So my question is this:
should BCP also copy over the compiled LIB files as necessary ?
or
is it standard procedure for users of BOOST to manually copy those complied library files themselves?
I recently started experimenting with BCP. It seems like any boost modules that require libraries will not be copied, but instead they need to be built using bjam.
For example, when you run bcp on your code it will output some 'INFO' statements like this:
INFO: tracking source dependencies of library date_time due to presence of BOOST_DATE_TIME_DECL...
INFO: tracking source dependencies of library smart_ptr due to presence of "void sp_scalar_constructor_hook...
Notice that in addition to the generated 'boost' folder containing a bunch of copied boost header files there will be a 'libs' folder along with Jam files (Jamroot, Jamfile.v2, etc).
I think you need to cd to the directories with the Jamfiles and use bjam to build the needed libraries.
Maybe this answer will help:
Building a subset of boost in windows

How to enable cmake to exclude a subdirectory from install?

I have been trying to build RPM packages for libc++ 3.3 on a RHEL 6.4 box. I need both static and shared libraries. So, I learned some basics of cmake and then modified the bundled CMakeList.txt. Got that part to work.
But since in RHEL 6.x, all 64-bit libraries should go to /usr/lib64 instead of /usr/lib, I have been attempting to use the following to get the job done:
(A) During building, I use
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
to have all library files (*.so* and *.a) located in lib64 rather than lib.
(B) Using a ADD_LIBRARY... command as shown below
ADD_LIBRARY(c++ STATIC ...
together with
set_target_properties(c++ PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
INSTALL(TARGETS c++
ARCHIVE DESTINATION lib${LIB_SUFFIX})
to get the static library installed in /usr/lib64.
(C) In addition, with
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so DESTINATION lib${LIB_SUFFIX})
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so.1 DESTINATION lib${LIB_SUFFIX})
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so.1.0 DESTINATION lib${LIB_SUFFIX})
to have shared libary also installed in /usr/lib64 too.
But a copy of the shared library is still installed in /usr/lib in the resulting RPM. How can I prevent it?
If I were to write a RPM spec file, the _libdir macro automatically handles this. With cmake, given the fact that I am still new to it, I would appreciate a hint/pointer as to the right directive to use.
Actually, with a helpful person in the cmake mailing list, I am now able to rid of the %dir /usr/lib in the generated spec file. It's actually quite simple: just cd to $CMAKE_SOURCE_DIR/lib and edit the CMakeLists.txt there. Append ${LIB_SUFFIX} to the two install DESTINATIONs. Regenerate the Makefile in the build subdirectory, and then make && make package. All library files go into /usr/lib64 as desired.
What I can see:
1) There's a missing space in ARCHIVE_OUTPUT_DIRECTORY${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}), should be ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
2) When are your .so files going to be build if you use ADD_LIBRARY(c++ STATIC ...?

Using Windows libraries with cgo

I'm trying to build a Go package which makes use of TagLib, and I'm having a little trouble figuring out exactly how to use the compiled libraries with cgo.
I've compiled TagLib, which has spit out tag.dll, tag.exp, and tag.lib in the taglib dir. There were also the taglib_c.* binaries in the bindings directory, but I'm assuming that I just ignore those.
How do I make use of the compiled libraries for use with Go? I have everything setup in the source from the project on OS X, but what do I need to do to make it compile on Windows? Does the compiled library (dll or static lib?) have to be in the same directory as the source? What about the headers?
Unfortunately I don't have a windows machine available to try this out myself, but theoretically, this should work. The steps I have listed are written with a unix perspective, but it should be directly translatable to Windows unless otherwise noted. For Windows, I like to use GitBash for my terminal as it comes with some useful unix tools.
Anyways, I'm gonna work through the entire process to make sure I'm not making any assumptions. first, we'll start with downloading and installing taglib. Assuming that you've downloading the 1.8 tarball that they have available, then I would install it locally in some folder in my computer:
/home/noj $ mkdir -p clibs/src
/home/noj $ cd clibs/src
/home/noj/clibs/src $ tar -xvf /home/noj/Downloads/
/home/noj/clibs/src $ cd taglib-1.8
/home/noj/clibs/src/taglib-1.8 $ cmake -DCMAKE_INSTALL_PREFIX=/home/noj/clibs -DCMAKE_RELEASE_TYPE=Release .
/home/noj/clibs/src/taglib $ make
/home/noj/clibs/src/taglib $ make install
The above code should install taglib locally for development in the folder /home/noj/clibs. If you take a look at the inside of the folder, you'll find subdirectories for bin, lib, and include.
So here's the funky part. The Windows standard is to dump dynamic lib files (*.dll) into the bin directory. Some open source libraries adhere to this and do that, others still dump the *.dll files in the lib directory since that's where they usually go in Unix systems. You'll want to take a look at the lib directory generated by the installation and copy any *.dll files that are generated over to the bin directory to make sure proper linking takes place without too much hackery.
Now for the go source code! At the top of your source code, you'll want to include the cgo meta comments to tell Go where to search for the libraries you want, as well as their headers (the include directory generated during the installation). Here's some Go source that tries to use the libraries we just built above:
package main
/*
#cgo LDFLAGS: -L/home/noj/clibs/lib -ltag -lstdc++
#cgo CFLAGS: -I/home/noj/clibs/include/taglib
#include <taglib.h>
*/
import "C"
import (
// normal imports
// ...
)
func main() {
// ...
}
Now, Windows, also requires you to add the directory where your *.dll files live to your PATH, so we'll go ahead and do that...
/home/noj $ export PATH=$PATH:/home/noj/clibs/bin
And now we should be ready to compile the code normally using go build within the Go's source directory.
Possible Problems:
So some problems you might run into is finding out that you don't have the necessary libraries to build taglib in Windows, though it sounds like you've already built it, so that should be fine. You'll notice that in the go source I added the LDFLAG for the standard c++ library. This is because taglib uses C++. If this turns out to be a problem, I would create a simple C program alongside your go code that interfaces with the c++ library and creates a C interface for it. From my experience, it's a lot easier to work with a C library and Go than with C++ and Go.

Resources