CMake 3 Link Libraries Using Relative Paths - makefile

I've got a shared library source directory that needs to be formatted in a particular way, and I've been unsuccessful in getting CMake to allow building of individual libraries.
Here's a basic example of the directories
libraries/
CMakeLists.txt
a/
CMakeLists.txt
a.h
src/a.cpp
test/
CMakeLists.txt
exe_test.cpp
b/
CMakeLists.txt
b.h
src/b.cpp
Library a depends on b. If I add_subdirectory() for both of them in the top-level CMakeLists.txt, I can build the whole libraries folder using cmake. However, I don't want to do this. I'd like to be able to build just b, and if I choose to build a, it automatically links to b using relative paths. For this example it may seem trivial, but imagine roughly two dozen libraries in this kind of format, and we'd like to avoid nesting.
target_link_libraries(a PUBLIC ../b) does not work. Neither does add_subdirectory(..).

Related

Include Makerules from sub.mk with Makefile.am

is it possible to not generate the Makerules from Makefile.am, but include the Makerules from a predefined sub.mk?
Well, I have a big Makefile-Project i want to build a custom App for.
Building an App for this project is done with a Makefile in the following structure:
PROJDIR ?= ../..
TARGET = myApp
SRC_C = main.c
include $(PROJDIR)/prog.mk
The actual makerules are hidden somewhere in prog.mk which requires the variables TARGET, SRC_C etc.
Now, i want to use an independent Automake project to generate the Makefile of my App.
Is it even possible to let Makefile.am generate a Makefile like the one above?
Can someone provide an example for this?
No, automake by design is not going to generate anything close to that, since it's a full stack to define your targets and it'll take care of building them.
You can use autoconf alone, by writing a template Makefile.in and have it substitute the variables you figure out at ./configure time, but that means you're essentially on your own to write the structure.

Using CMake to resolve #include dependencies in an exotic language

I'm trying to use CMake as my build tool driver (I make it clear at once that I'm quite new to CMake since this my first on-my-own CMake project). My project is mainly C with some files in an exotic language I'll call here Z. These Z files must be processed by their Z compiler to produce .h and .c files.
I managed to tweak CMake handle Z compiling and dependencies between plain C files and generated Z -> .h header with
add_custom_command( ...*details omitted*... )
set_source_file_properties(*generated-.h* PROPERTIES GENERATED TRUE)
and CMake C-#include scanner does properly the rest of the job.
Now, Z files use something equivalent to C #include construct and I'd like to make profit of automatic recompilation when one of the Z-included files changes.
If a.Z includes inc.Z, I tried:
set_source_file_properties(a.Z PROPERTIES OBJECT_DEPENDS inc.Z)
but that doesn't trigger automatic recompilation of a.Z.
CMake manual says this property was introduced for this purpose and is no longer necessary for C/C++. However it is ineffective in my Z case.
If I modify my custom command as follows:
add_custom_command( ... DEPENDS inc.Z ...)
I get the desired result, but not all Z files depend on inc.Z (another one might depend on inc2.Z).
I then tried to generate dynamically the DEPENDS list with
get_source_file_property(dependencies ${filename} OBJECT_DEPENDS)
if(dependencies STREQUAL "NOTFOUND")
unset(dependencies)
else()
string(REPLACE ";" " " dependencies "${dependencies}")
endif()
add_custom_command(... DEPENDS $filename "$dependencies" ...)
and make errors out with
Make[2]: *** no rules to build target `-- content of dependencies variable --'
Note: error is the same with or without double quotes around variable substitution
I guess CMake interpreted my list of dependencies as a single (non-existent) filename and make was unable to handle that. Anyway, the files mentionned in the dependencies variable are not meant to be compiled, only to be included somewhere. They must make their way to make only as dependencies.
Which direction should I go to achieve the desired result?
Recall this is my first on-my-own CMake project and I certainly made newbie errors.
FWIW, my platform is Linux with CMake 2.8.9 (not bleeding edge but I'm only exploring) and KDevelop 4.x
Thanks for your help.

How to build a C dependency of go project in a subdirectory

I am writing a Go wrapper for a C library in Go. The problem is, that the C library is not available on many Linux distributions, so I want a solution where i "go get github.com/me/mylibrary" does not require anybody to have the library installed.
One solution would be to just add the source of the library into a sub directory. Then when my project is build with go get I need to automatically build this library, too. But I have no idea how I can automate this.
Alternatively I could have a script that downloads the source, extracts and builds it
But I have no Idea how to connect these build steps with the go build tool.
linking a static library is also not the easiest.
#cgo linux LDFLAGS: ./MyLib/lib/libMyLib.a -lstdc++ -lm -lX11
works as long as i build from my library, but as soon as I want to build from another project the relative path is from that project and not from my library, so it fails.
As per http://golang.org/cmd/cgo/#hdr-Using_cgo_with_the_go_command
When the Go tool sees that one or more Go files use the special import
"C", it will look for other non-Go files in the directory and compile
them as part of the Go package. Any .c, .s, or .S files will be
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
compiled with the C++ compiler.
So you can include the C library source in your repository and go will build it automatically. That page also explains how to pass build flags to the compilers and probably anything else you might need to know.

Building a Shared Library but linking against a Static One

I have an Autogen Makefile.am that I'm trying to use to build a test program for a shared library. To build my test binary, I want to continue building the shared library as target but I want the test program to be linked statically. I've spent the last few hours trying to craft my Makefile.am to get it to do this.
I've tried explicitly changing the LDADD line to use the .a version of the library and get a file not found error even though I can see this library is getting built.
I try to add the .libs directory to my link path via LDFLAGS and still it can't find it.
I tried moving my library sources to my test SOURCES list and this won't work because executable object files are built differently than those for static libraries.
I even tried replicating a lib_LIBRARIES entry for the .a version (so there's both a lib_LTLIBRARIES and a lib_LIBRARIES) and replicate all the LDFLAGS, SOURCES, dir and HEADERS for the shared version as part of the static version (replacing la with a of the form _a_SOURCES = _la_SOURCES. Still that doesn't work because now it can't figure out what to build.
My configure.ac file is using the default LT_INIT which should give me both static and dynamic libraries and as I said it is apprently building both even if the libtool can't see the .a file.
Please, anyone know how to do this?
As #Brett Hale mentions in his comment, you should tell Makefile.am that you want the program to be statically linked.
To achieve this you must append -static to your LDFLAGS.
Changing the LDFLAGS for a specific binary is achieved by changing binary_LDFLAGS (where binary is the name of the binary you want to build).
so something like this should do the trick:
binary_LDFLAGS = $(AM_LDFLAGS) -static

CMAKE: Build library and link against it

I'm trying to use cmake (on Linux with GNU make and g++) to build a project with two sub-directories: MyLib and MyApp. MyLib contains source for a static library; MyApp needs to link against that library. I'm trying to build on Linux with generated makefiles using the following CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (MyProj)
include_directories (MyLib)
file(GLOB MyLibSrc MyLib/*.cpp)
add_library(MyLibrary STATIC ${MyLibSrc})
file(GLOB MyAppSrc MyApp/*.cpp)
add_executable(MyApplication ${MyAppSrc})
target_link_libraries(MyApplication MyLibrary)
This 'almost' works. It fails at link time because while it generates libMyLibrary.a - it is in the root. When I add:
link_directories(${MyProj_BINARY_DIR})
it makes no difference.
I've got a few (inter-linked) questions:
What's the best way to coerce cmake into building my library and executable into a 'staging directory' — say MyStage — to keep targets separate from source?
How do I convince cmake to link the application against the library?
If I wanted to build a debug and a release version, what's the best way to extend my cmake scripts to do this — making sure that the debug application links against the debug library and the release application against the release library?
I'm a relative newcomer to cmake. I've read what I can find on the web, but find myself struggling to get my library to link with my executable. This sort of a configuration, to my mind, should be quite common. An example from which to crib would be very helpful, but I've not found one.
Well, it is better to read this example and do exactly as suggested.
cmake_minimum_required (VERSION 2.6)
project (MyProj CXX)
add_subdirectory(MyLib)
add_subdirectory(MyApp)
Then for each subdirectory specified, CMakeLists.txt files are created
MyLib\CMakeLists.txt
file(GLOB SRC_FILES *.cpp)
add_library(MyLib ${SRC_FILES})
MyApp\CMakeLists.txt
file(GLOB SRC_FILES *.cpp)
add_executable(MyApp ${SRC_FILES})
target_link_libraries(MyApp MyLib)
Use "out of the source build". Make a directory used only for build and while in it, call
cmake <path to the sources, it may be relative>
Either use
link_directories(${MyProj_BINARY_DIR}/MyLib)
or make CMakeLists.txt in each subdirectory - that would be better for project larger than very small.
This is a bit tricky, check out CMAKE_BUILD_TYPE in the docs (you can set it and/or "if" by it). You can also set it from command line:
cmake -DCMAKE_BUILD_TYPE=Debug
I've discovered the 'optimal' solution to (1)... so, thought I should post it here:
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY MyStage)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY MyStage)
The thing that confused me previously is that static libraries are not considered a LIBRARY by Cmake - they're considered to be ARCHIVEs.
Do not add libraries and executables in the root Cmakelists.txt. Add these libraries and executables in Cmakelists.txt of subdirectories.

Resources