Autotools Setup for Static and Shared Libraries - makefile

We have a large code base that I'm converting to autotools to help target multiple platforms / configurations. Basically, we have:
|-- configure.ac
|-- Makefile.am
|-- dependency1
| `-- Makefile.am
|-- dependency2
| `-- Makefile.am
`-- dependency3
`-- Makefile.am
The dependency folders are common across many projects, so The Makefile.am files create libdependencyX.la files. In the root Makefile.am, I then use LIBADD to combine everything to create a final shared library. This all works create.
We have the need to create both shared and static versions of our library. How would I go about this? All of the dependencies just use LTLIBRARIES to make everything.
The original solution was just a giant Makefile that created a series of .o files and then building the resulting .so or .a in the end.
Update 2015-03-11
The issue I'm having is that I can get static or shared, but not both. The root Makefile.am looks like this for the final library.
lib_LTLIBRARIES = libroot.la
libroot_la_SOURCES = root.c
libroot_la_LIBADD = dependency1/libdependency1.la \
dependency2/libdependency2.la \
dependency3/libdependency3.la
libroot_la_LDFLAGS = -shared
Switching the -shared to -static gives me the .a, but how can I get both? --enable-shared / --enable-static doesn't seem to change anything.

It seems my issue is with the libretto_la_LDFLAGS line. Leaving that out and using make install gives both the .a and .so files in the prefix specified.

Related

Building libraries with bazel and hardcoding dependencies into them

Is it possible to hard code dependencies into the libraries build with bazel. The reason is that if I build somelib I can use it in the workspace but as soon as I copy the lib somewhere else I loose all dependencies (bazel cache). Witch creates a problem when I want to deploy the libraries into the system or install.
some_folder
|
thirdparty
|_WORKSPACE
|_somelib
| |_src
| |_ a.c
| |_ BUILD
| |_include
| |_a.h
|_include
|_ b.h
It sounds like you want to build a fully statically linked library. This can be done in Bazel by building the library using cc_binary with the linkshared attribute set to True. According to the documentation you also have to name your library libfoo.so or similar.
What enables the static library here is cc_binary's linkstatic attributes behavior. When True, which is the default, all dependencies that can be linked statically into the binary will be. Note that linkstatic does NOT behave the same on cc_library, see the documentation.
So, basically you want something like this in your BUILD file
cc_binary(
name = "libfoo.so",
srcs = [...],
hdrs = [...],
linkshared = 1,
#linkstatic = 1 # This is the default, you don't need to add this.
)
Good luck!

Installing CMake package config files for MacOS frameworks

I created a versioned MacOS framework with CMake and stumbled over the question where to install the package config files sample-config.cmake, sample-config-version.cmake, sample-exports.cmake, sample-exports-release.cmake.
The framework is versioned so the structure is roughly as follows:
<sample.framework>
|-- Headers # link to Versions/Current/Headers
|-- Resources # link to Versions/Current/Resources
+-- Versions
|-- Current # link to B
+-- B
|-- Headers
+-- Resources
|-- CMake
+-- Info.plist
I use CMakes CMakePackageConfigHelpers macros to generate a package config file from a template sample-config.cmake.in with the content
#PACKAGE_INIT#
include("${CMAKE_CURRENT_LIST_DIR}/sample-export.cmake")
CMake does not mention versioned frameworks and recommends to install the files into the directory Resources/CMake.
I did so by calling
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sample-config.cmake"
DESTINATION sample.framework/Resources/CMake
COMPONENT development
)
The generated file looks like this:
####### Expanded from #PACKAGE_INIT# by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was sample-config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
include("${CMAKE_CURRENT_LIST_DIR}/sample-export.cmake")
Error:
There's a difference in the generated config file whether I install those files to Resources/CMake or to Versions/B/Resources/CMake although both point to the same directory.
When installing via the Resources link to Resources/CMake the call to set PACKAGE_PREFIX_DIR is generated as
`get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)`
but when installing via Versions/B/Resources/CMake it is generated as
`get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../../" ABSOLUTE)`
As a consequence of this the package cannot be found by find_package(sample CONFIG) when installing to Versions/B/Resources/CMake.
Did anybody was facing this error before?
Thanks for any input on this.

Configuration files in separate directory in case of Autotools

I am implementing CPPUTEST for my application along with Autotools, but the final makefile generated in subdirectories is not able to make the final build.
Folder Structure:
|
+- Build_output: holds executable for CPPUTEST
+- Configure : holds `configure.ac` and `Makefile.am`
+- Src: contains source files that contain functions and makefile.am
+- Test: contains test file
+- build: shell script for creating executables.
Snapshot added: build structure
build structure continue
Usually I see example of autotools every where configuration files is kept outside, not inside the configure folder.
Configure.ac inside configure folder:
AC_INIT([cpputest], [1.0], [])
AM_INIT_AUTOMAKE([
-Wall -Werror foreign subdir-objects
])
AC_PROG_CXX
AC_CONFIG_FILES([
Makefile
../src/Makefile
../test/Makefile
])
AC_OUTPUT
Makefile.am inside configure folder:
SUBDIRS = \
../src \
../test
Shell script present outside "build"
#!/bin/sh
cd configure
autoreconf -i
./configure
make check
When I run my shell script, the make file is getting generated inside src and test folder but when I try make check
it executes cd ../.. ---> screenshot attached
./build execution
Is there any other option needed to add in configure.ac or makefile.am ?

Creating a CMakeLists.txt with header and mains

I have divided my program in 3 folders: build, include, and src.
Build is where I want all the files created from the Makefile to go, include contains a "file.h", and src contains a "file.c" and "main.c".
I have written this in the CMakeLists.txt file:
cmake_minimum_required (VERSION 3.5.1)
project(Listas_interlazadas)
include_directories(${include})
add_executable(ejec
src/main.c
src/listas.c
include/listas.h
)
Nonetheless, I believe I should somehow include the src folder. Also, how do I send all files to the build folder? From the terminal, right?
Thanks.
Your code need some minor reworks.
The command include_directories must point to an valid path
Add header files only in case they are not included in any of your source files
Assume the following structure of your project:
project
+--source
| +--CMakeLists.txt
| +--src
| | +--main.c
| | +--listas.c
| +--include
| +--listas.h
+--build
Reworked CMakeLists.txt
cmake_minimum_required (VERSION 3.5.1)
project(Listas_interlazadas)
include_directories(include)
add_executable(ejec
src/main.c
src/listas.c
)
Back to your questions:
Add the sources: You already inserted the required source files. See add_executable.
Copy sources to build folder: This is not necessary.
To build your project, you have to run cmake and make (or nmake on windows).
Steps:
Open a command shell
Move to the build folder
Run: cmake ../source
Run: make
Some important parts of a CMakeLists.txt

No rule to make target 'mesh2D.h', needed by 'all-am'

I have the following project tree :
src
├── Converters
├── datamodel
Inside datamodel/ I have a header that I want to include in a source cpp file inside Converters/.
However I get the following error :
No rule to make target 'mesh2D.h', needed by 'all-am'
This is my automake Makefile.am inside Converters/:
include $(top_srcdir)/adm_local/unix/make_common_start.am
AM_CPPFLAGS+= \
-I$(top_srcdir)/src/datamodel
libSource_SOURCES=\
source.cpp \
source.h
include_HEADERS=\
mesh2D.h
SUBDIRS=
include $(top_srcdir)/adm_local/unix/make_common_end.am
Thanks for your help!
I would move the
include_HEADERS = mesh2D.h
line to datamodel/Makefile.am if you are using recursive make, or
include_HEADERS += %reldir%/mesh2D.h
to datamodel/Makefile-files if you use a single Makefile.am with per-directory includes or
include_HEADERS += datamodel/mesh2D.h
if you are using a single Makefile.am without per-directory includes.
Note that using include_HEADERS will install the mesh2D.h file into /usr/local/include. If mesh2D.h is just needed to compile your program, use noinst_HEADERS instead of include_HEADERS to include mesh2D.h in the distribution tarball (make dist) without installing it (make install).

Resources