Skip to content

Commit

Permalink
fix: windows dll linker with same flags as posix
Browse files Browse the repository at this point in the history
now executing sources on windows can link DLL libs found in paths (and
system paths) using -l name just like on posix systems
  • Loading branch information
jaromil committed Jan 12, 2025
1 parent 8f8d662 commit 3f65135
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 24 deletions.
3 changes: 2 additions & 1 deletion build/init.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ CFLAGS ?= -O2 ${cflags_stack_protect}

cflags := ${CFLAGS} ${cflags_includes}

SOURCES := src/file.o src/cjit.o src/elflinker.o \
SOURCES := src/file.o src/cjit.o \
src/elflinker.o src/winlinker.o \
src/main.o src/assets.o \
src/cwalk.o src/array.o \
src/muntar.o src/tinflate.o src/tinfgzip.o \
Expand Down
33 changes: 15 additions & 18 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ static bool cjit_setup(CJITState *cjit) {
char *extra_cflags = NULL;
extra_cflags = getenv("CFLAGS");
_err("CFLAGS: %s",extra_cflags);
debug(" -C %s",extra_cflags);
tcc_set_options(tcc(cjit), extra_cflags);
}
#if defined(WINDOWS)
Expand All @@ -212,10 +213,10 @@ static bool cjit_setup(CJITState *cjit) {
// add(libpaths,cjit->tmpdir);
// tinyCC needs libtcc1.a in library path (not added as file)
#if !defined(SHAREDTCC)
debug(" -L %s",cjit->tmpdir);
tcc_add_library_path(tcc(cjit),cjit->tmpdir);
tcc_add_library_path(tcc(cjit), "."); debug(" -L %s",".");
tcc_add_sysinclude_path(tcc(cjit), cjit->tmpdir);
tcc_add_sysinclude_path(tcc(cjit), ".");
tcc_add_sysinclude_path(tcc(cjit), "include"); // TODO: check if exists
#endif
{ // search libs also in current dir
char pwd[MAX_PATH];
Expand All @@ -231,11 +232,13 @@ static bool cjit_setup(CJITState *cjit) {
char *tpath;
// TODO: support WIN32 here: "C:\\Windows\\System32"
add(libpaths,"C:\\Windows\\SysWOW64");
debug(" -L %s","C:\\Windows\\SysWOW64");
tcc_add_library_path(tcc(cjit), "C:\\Windows\\SysWOW64");
// tinycc win32 headers
plen = strlen(cjit->tmpdir)+strlen("/tinycc_win32/winapi")+8;
tpath = malloc(plen);
cwk_path_join(cjit->tmpdir,"/tinycc_win32/winapi",tpath,plen);
debug(" -I %s",tpath);
tcc_add_sysinclude_path(tcc(cjit), tpath);
free(tpath);
// windows SDK headers
Expand All @@ -244,8 +247,10 @@ static bool cjit_setup(CJITState *cjit) {
plen = strlen(sdkpath)+16;
tpath = malloc(plen);
cwk_path_join(sdkpath,"/um",tpath,plen); // um/GL
debug(" -I %s",tpath);
tcc_add_sysinclude_path(tcc(cjit), tpath);
cwk_path_join(sdkpath,"/shared",tpath,plen); // winapifamili.h etc.
debug(" -I %s",tpath);
tcc_add_sysinclude_path(tcc(cjit), tpath);
free(tpath);
}
Expand Down Expand Up @@ -323,16 +328,13 @@ bool cjit_status(CJITState *cjit) {
for(i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->libs,i));
}
#if defined(UNIX)
resolve_libs(cjit);
used = XArray_Used(cjit->reallibs);
if(used) {
_err("Lib files (%u)",used);
for(i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->reallibs,i));
}
#endif

}
return true;
}
Expand Down Expand Up @@ -536,15 +538,14 @@ int cjit_link(CJITState *cjit) {
return 1;
}
// resolve library files on UNIX systems
#if defined(UNIX)
int found = resolve_libs(cjit);
for(int i=0;i<found;i++) {
char *f = XArray_GetData(cjit->reallibs,i);
if(f) {
tcc_add_file(tcc(cjit), f);
}
}
#endif
debug(" -o %s",cjit->output_filename);
return( tcc_output_file(tcc(cjit),cjit->output_filename));
}

Expand All @@ -557,16 +558,16 @@ int cjit_exec(CJITState *cjit, int argc, char **argv) {
_err("%s: CJIT already executed once",__func__);
return 1;
}
// resolve library files on UNIX systems
#if defined(UNIX)
debug("resolve paths to library files (%i)",
XArray_Used(cjit->libs));
int found = resolve_libs(cjit);
for(int i=0;i<found;i++) {
char *f = XArray_GetData(cjit->reallibs,i);
if(f) {
debug(" +file: %s",f);
tcc_add_file(tcc(cjit), f);
}
}
#endif
int res = 1;
int (*_ep)(int, char**);
// relocate the code (link symbols)
Expand Down Expand Up @@ -664,7 +665,7 @@ void cjit_add_include_path(CJITState *cjit, const char *path) {
}
tcc_add_include_path(tcc(cjit), toadd);
free(toadd);
debug("+I %s",path);
debug(" -I %s",path);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library_path(CJITState *cjit, const char *path) {
Expand All @@ -678,21 +679,17 @@ void cjit_add_library_path(CJITState *cjit, const char *path) {
#elif !defined(SHAREDTCC)
tcc_add_library_path(tcc(cjit), toadd);
#endif
debug("+L %s",toadd);
debug(" -L %s",toadd);
free(toadd);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library(CJITState *cjit, const char *path) {
#if defined(UNIX)
add(libs,path);
#else
tcc_add_library(tcc(cjit), path);
#endif
debug("+l %s",path);
debug(" +l %s",path);
}
void cjit_set_tcc_options(CJITState *cjit, const char *opts) {
tcc_set_options(tcc(cjit),opts);
debug("+O %s",opts);
debug(" +O %s",opts);
}

#define MAX_STRING 2040
Expand Down
8 changes: 4 additions & 4 deletions src/cjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ struct CJITState {
bool done_exec;
// INTERNAL
// sources and libs used and paths to libs
void *sources;
void *libs;
void *libpaths;
void *reallibs;
void *sources; // xarray of source files loaded
void *libs; // xarray of library names to be resolved
void *libpaths; // xarray of library paths to be searched
void *reallibs; // xarray of paths made by resolve_libs()
};
typedef struct CJITState CJITState;

Expand Down
3 changes: 2 additions & 1 deletion src/elflinker.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,14 @@ int resolve_libs(CJITState *cjit) {
int i,ii;
int libpaths_num, libnames_num;
char *lpath, *lname;
int found = 0;
int found = -1;
// search in all paths if lib%s.so exists
// TODO: support --static here
libpaths_num = XArray_Used(cjit->libpaths);
libnames_num = XArray_Used(cjit->libs);
for(i=0;i<libnames_num;i++) {
lname = XArray_GetData(cjit->libs,i);
found = -1;
for(ii=0;ii<libpaths_num;ii++) {
lpath = XArray_GetData(cjit->libpaths,ii);
snprintf(tryfile,PATH_MAX-2,"%s/lib%s.so",lpath,lname);
Expand Down
68 changes: 68 additions & 0 deletions src/winlinker.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Library path resolver from lib names on Windows systems
*
* Copyright (c) 2024-2025 Dyne.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <platforms.h>
#if defined(WINDOWS)

#include <stdio.h>
#include <sys/stat.h>

#include <cjit.h>
// #include <cwalk.h>
#include <array.h>

#define debug(fmt,par) if(cjit->verbose)_err(fmt,par)

// takes the list of cjit->libpaths and cjit->libs
// then resolves them all looking for ${lib}.dll in paths
int resolve_libs(CJITState *cjit) {
char tryfile[PATH_MAX];
int i,ii;
int libpaths_num, libnames_num;
char *lpath, *lname;
bool found = false;
struct stat st;
// search in all paths if lib%s.so exists
// TODO: support --static here
libpaths_num = XArray_Used(cjit->libpaths);
libnames_num = XArray_Used(cjit->libs);
for(i=0;i<libnames_num;i++) {
found=false;
lname = XArray_GetData(cjit->libs,i);
for(ii=0;ii<libpaths_num;ii++) {
lpath = XArray_GetData(cjit->libpaths,ii);
snprintf(tryfile,PATH_MAX-2,"%s/%s.dll",lpath,lname);
debug("resolve_libs try: %s",tryfile);
if (stat(tryfile, &st) == 0) {
XArray_AddData(cjit->reallibs,
tryfile,strlen(tryfile));
debug("library found: %s",tryfile);
found=true;
break;
}
}
if(!found)
_err("Library not found: %s.dll",lname);
// continue anyway (will log missing symbol names)
}
return(XArray_Used(cjit->reallibs));
}

#endif // defined(WINDOWS)

0 comments on commit 3f65135

Please sign in to comment.