Is it possible to install the debug and release variant of a library with same command? - boost-build

I am using the following Jamfile ( in directory /home/morpheus/base/CDef ) :
lib CDef : [ glob *.cpp ] : static ;
install libCDef
: CDef
: LIB
"/home/morpheus/base_install/lib"
: release
;
install _libCDef_D
: CDef
: LIB
"/home/morpheus/base_install/libdebug"
: debug
;
I was wondering if the two install lines can be changed to one which has both the debug and release directives.
Also to use the libraries in a different Jamfile in a different directory ( /home/morpheus/FSLR ) I am using the following Jamfile to build the exe callFSLR :
lib CDef : : release CDef /home/morpheus/base_install/lib ;
lib CDef : : debug CDef /home/morpheus/base_install/libdebug ;
exe callFSLR : call_FSLR.cpp CDef : : debug release ;
install install-bin
: callFSLR
: "/home/morpheus/base_install/bin" release
;
I believe using "use-project" to refer to CDef in the Jamfile /home/morpheus/base/CDef/Jamfile is probably adviseable ?

(I think some stuff is missing from your jam rules, possibly due to formatting.)
Yes, you definitely can define both the debug and production targets with the same rule, using conditional requirements. An example is even the documentation of the install rule.
I believe your original rules look like
install libCDef
: CDef
: <install-type>LIB
<location>"/home/morpheus/base_install/lib"
: <variant>release ;
install _libCDef_D
: CDef
: <install-type>LIB
<location>"/home/morpheus/base_install/libdebug"
: <variant>debug ;
You'll want to make the location feature dependendent on the variant, like so:
install libCDef
: CDef
: <install-type>LIB
<variant>release:<location>"/home/morpheus/base_install/lib"
<variant>debug:<location>"/home/morpheus/base_install/libdebug"
;
As for the second question, yes, use-project would help, although it shouldn't be necessary. You want to do this
exe callFSLR : call_FSLR.cpp ../base/CDef//CDef ;
../base/CDef//CDef refers to the target named CDef defined in the project (directory) ../base/CDef. This refers to the library rule, so boost build will use the version of the library in the bin directory, not the version created by the install rule. (This might matter if you have dynamic library issues.) Also, you don't need the lib CDef immediately above this rule.
To avoid the clumsiness of the ../base/CDef, you could use the use-project rule to make a new definition for the project. Then should you reorganize the directory structure, you only have one place to change it.
use-project /CDef-project : ../base/CDef ;
exe callFSLR : call_FSLR.cpp /CDef-project//CDef ;
Another possibility, if you are going to use the one target in this one Jamfile, is to use the alias rule.
alias CDef : ../base/CDef//CDef ;
exe callFSLR : call_FSLR.cpp CDef ;

Related

Meson creates build files which will not compile

I am trying to port an existing code tree to the meson build system on a centos 7 machine. Meson configure works fine, but when I try to compile, it fails. The code is proprietary, so I have created an example that illustrates the problem (accurately enough, I hope.) I am not at liberty to restructure the directory tree.
Here's the tree:
mesonex/
alpha/
beta/
alpha/
inc/
funcs.h
numbers.h
src/
numbers.cpp
funcs.cpp
src/
example.cpp
meson.build
My meson.build:
project('example', 'cpp')
srcs=['example.cpp']
srcs+='../beta/alpha/src/funcs.cpp'
srcs+='../beta/alpha/src/funcs.cpp'
incdirs=include_directories('../beta/alpha/inc')
executable('example', srcs, include_directories: incdirs)
here is the main example.cpp file:
#include <iostream>
#include "../beta/alpha/inc/numbers.h"
#include "../beta/alpha/inc/funcs.h"
int main()
{
std::cout << "Hello" << std::endl;
std::cout << interestingNumber() << std::endl;
std::cout << interestingFunc() << std::endl;
}
These are the supporting cpp files:
// funcs.cpp
#include "../inc/numbers.h"
float interestingFunc()
{
return (interestingNumber()+1)/2;
}
// numbers.cpp
float interestingNumber()
{
return 11.3355;
}
And these are the header files:
// funcs.h
float interestingFunc();
// numbers.h
float interestingNumber();
Please note that the duplication in directory names is intentional. Maybe this confuses meson in figuring out how to handle the #includes?
This is just one example of many different build strategies I have tried.
I see right off the bat an issue that might just be an issue with your example, and not with your actual code: Meson considers the meson.build file with the project() call to be the "root" of the source directory structure. You cannot ask it to include files outside of the root. It would be about like cp /../foo . on a Unix-like OS. This may just be a mistake in your example, since this isn't the real code of course.
So, if we rewrite this as (mesonex/alpha/meson.build):
# no project(), that would be in mesonex/meson.build)
sources = files(
'example.cpp',
'../beta/alpha/src/funcs.cpp',
'../beta/alpha/src/numbers.cpp', # you have a typo in your example, funcs.cpp is listed twice.
)
executable(
'example',
sources,
include_directories : include_directories('../beta/alpha/inc'),
)
Should work.
Note, that you might want to consider using a convenience static library instead of reaching back to the code, as this is best practice, you could write something like (mesonex/alpha/beta/meson.build):
lib_beta = static_library(
'beta',
['src/funcs.cpp', 'src/numbers.cpp']
)
idep_beta = declare_dependency(
link_with : lib_beta,
include_directories : include_directories('.'),
)
and then in (src/meson.build):
executable(
'example',
'source.cpp',
dependencies : idep_beta
)
is all you need, as the idep_beta carries both the linkage and the include information.
This is a follow on - the solution worked for my example but not for the actual code. My model must have been incomplete (in a way I haven't determined yet.) The configuration stage works, but in the compile stage the #includes in the cpp source are flagged with a "File or directory does not exist." How does meson reconcile the specified include directories with #include statements in the source? The #include paths may be relative to the actual directory of the actual cpp source. Does this mean I have to edit all the #includes in all the sources - that would be a real negative. We work with some VERY large code bases.

Using CMake targets in Visual Studio projects

I am pretty comfortable with CMake when used in Linux. That is, I use CMake to logically group my code into "targets" and abstract such things as "include directories" and other dependencies. Say, inside a large project my modus operandi would be to add_library(..SHARED) for a bunch of related files that provide one logically coherent unit, and target_link_libraries(...) to it from somewhere else.
(Of course, idiosyncrasies of CMake is another topic. I won't digress to discussions about e.g. its syntax.)
Now, for Windows 10. I fired up Visual Studio 2019 Community with the MSVC toolchain (that is, not WSL/WSL2), and created a CMake Project using VS's "New Project" wizard.
It has created for me some boilerplate code, and the whole project tree looks as below:
In this image, EnRouteGeneratedLibrary is something I added as the next step. Inside it, I have one *.hpp file:
#pragma once
template<typename T>
class __declspec(dllexport) SampleTemplateKlass {
public:
T sum(T x, T y) { return x + y; }
};
template class __declspec(dllexport) SampleTemplateKlass<int>;
and the CMakeLists.txt's contents are as follows:
add_library(${TRG} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/SampleTemplateKlass.hpp)
# set_target_sources(${TRG} PUBLIC SampleTemplateKlass.hpp)
set_target_properties(${TRG} PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(${TRG} PUBLIC .)
set(WINDOWS_EXPORT_ALL_SYMBOLS 1)
Finally, in when building a simple "Hello World" executable, I have the following:
//
#include "SampleProjectWithDll.h"
#include "SampleTemplateKlass.hpp"
using namespace std;
int main()
{
cout << "Hello CMake." << endl;
SampleTemplateKlass<int> tmp;
std::cout << tmp.sum(42, 314) << std::endl;
return 0;
}
(This is the boilerplate code created by VS + my additions).
I link as follows:
# CMakeList.txt : CMake project for SampleProjectWithDll, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
add_subdirectory(EnRouteGeneratedLibrary)
# Add source to this project's executable.
add_executable (SampleProjectWithDll "SampleProjectWithDll.cpp" "SampleProjectWithDll.h")
target_link_libraries(SampleProjectWithDll PUBLIC SampleLibrary)
# TODO: Add tests and install targets if needed.
When building all this, I get two errors,
LNK2001 unresolved external symbol _DllMainCRTStartup and LNK1120 1 unresolved externalswith SampleLibrary.dll in the "File" field of the error panel.
The question is, how to make this simple "Hello World" compile and execute under Windows,
using the CMake infrastructure?

Cannot get Boost to build correctly

I needed to built Boost.Python to work for version 3.2 and I keep running into problems. I followed the instructions in the Getting Started Guide — both the general instructions and those specifically about Boost.Python — and I can't get it to work.
Here's the program I'm trying to run and the link error I'm getting:
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(test) { }
int main() { return 0; }
1>LINK : fatal error LNK1104: cannot open file 'boost_python-vc100-mt-1_48.lib'
Indeed, there is no such file, but there is a 'libboost_python-vc100-mt-1_48.lib' file. (Unsurprisingly, if I try to change its name, it'll give another link error.)
The command I used to install the libraries was:
C:\...\boost_1_48_0> b2 --build-dir=C:\Boost toolset=msvc --build-type=complete install
And the content of my 'user-config.jam' file in my home directory was:
using python : 3.2 : C:/Programming/PythonX86/Python32 ;
It looks like you're only building the static boost_python library binary. Have you tried the following command line options for b2?
link=shared runtime-link=shared
Also, if linking to a static library is acceptable for your needs, adding BOOST_PYTHON_STATIC_LIB to your preprocessor definitions should do the trick...

How do I use a library in multiple classes w/o getting "multiple definition" errors

I am starting a new c++ project and I want to use Boost.Build / bjam.
I'm getting "multiple definition" errors because, I think maybe, the jam file is not written correctly or I am not including the headers correctly or, perhaps, the library is not written well, which I have not investigated.
main.cpp uses libA.
rest.cpp uses libA.
libA is a header library. Therefore I need to include headers for libA in both main.cpp and rest.cpp of the compiler complains about namespaces etc...
I'm using gcc on debian.
Here are my jam files:
Jamroot.jam
import os ;
import modules ;
path-constant boost-root : "/home/dude/include/boost_1_48_0" ;
path-constant cgi-root : "/home/dude/include/cgi-0.7.1/libs/cgi/build" ;
path-constant BOOST_BUILD_PATH : "$(boost-root)/tools/build/v2" ;
# path-constant include-dir : /usr/local/include ;
use-project /boost/ : $(boost-root) ;
use-project /boost/cgi/ : $(cgi-root) ;
lib libsoci_core : : <file>/usr/local/lib/libsoci_core.so ;
lib libsoci_odbc : : <file>/usr/local/lib/libsoci_odbc.so ;
lib libboost_log : : <file>/usr/local/lib/libboost_log.so ;
Jamfile.jam
project hello_fcgi
: requirements
<library>/boost/cgi/
<library>/boost/system/
<library>/boost/thread/
<include>/usr/local/include/soci/
<include>/usr/local/include/soci/odbc/
;
# exe rest : rest.cpp hello /boost/regex/ libboost_log libsoci_core libsoci_odbc ;
exe hello : main.cpp rest.cpp cms.cpp /boost/regex/ libboost_log libsoci_core libsoci_odbc ;
# Our install rule (builds binaries and copies them to <location>)
install install
:
hello
:
<location>/var/www/localhost/cgi-bin/
;
# Only install example if you use `bjam install' or equivalent
explicit install ;
The errors I get are repetitions of:
Performing configuration checks
- has_icu builds : yes
...patience...
...patience...
...found 3228 targets...
...updating 1 target...
gcc.link bin/gcc-4.4.5/debug/hello
bin/gcc-4.4.5/debug/rest.o: In function `basic_client':
/usr/include/c++/4.4/exception:62: multiple definition of `boost::cgi::common::basic_client<boost::cgi::common::tags::fcgi>::basic_client()'
bin/gcc-4.4.5/debug/main.o:/home/dude/include/cgi-0.7.1/boost/cgi/fcgi/client.hpp:44: first defined here
This defect report looks relevant: it seems this "header only" library has slipped up on a few things which aren't really just header only.

can't compile with libpqxx and xcode4 (c++)

I am trying to use libpqxx (3.1) in my C++ project in order to connect to my postgresql database. I am using the lastest version of xcode (xcode 4).
I correctly made the install (./configure, make and make install) and added the library in my header search path and library search path.
header search path : /usr/local/include
library search path : /usr/local/lib
Then,
#include <pqxx/pqxx>
And i get the following error in the pqxx/cursor.hxx file:
stateless_cursor(
transaction_base &trans,
const PGSTD::string adopted_cursor) :
**m_cur(trans, adopted_cursor, up, op)**
{
// Put cursor in known position
m_cur.move(cursor_base::backward_all());
}
No matching constructor for initialization for 'internal::sql_cursor'
Should I edit this file ?
Thanks for your help.
Finally, I edited the library and changed:
m_cur(trans, adopted_cursor, up, op)
to :
m_cur(trans, adopted_cursor, op)
to match the constructor signature.